实例化空 IQueryable,以便与 Linq 一起使用到 sql

我需要能够在 Linq 查询中拥有一个可选参数,或者在需要从查询中删除可选参数时,能够将查询分配给类似 IF 的 var。

如果我在 IF 语句中设置了 query var,那么当我尝试遍历它时,它会告诉我 var 在上下文中不存在。

if (whichGroup == "All")
{
var listOppLineData = (from o in db.opportunity_vws
where o.fiscal_yr_and_qtr == qtr
select o
);
}
else
{
var listOppLineData = (from o in db.opportunity_vws
where o.fiscal_yr_and_qtr == qtr && o.Group == whichGroup
select o
);
}
            

foreach (var data in listOppLineData)  //listOppLineData doesn't exist here
{
...

我想我需要在 IF 语句之前设置 var,但是我不知道要设置它为什么。

var listOppLineData = ""; // gives me
Cannot implicitly convert type 'System.Linq.IQueryable<Forecast.Models.opportunity_vw>' to 'string'


IQueryable listOppLineData = new IQueryable(); //gives me
Cannot create an instance of the abstract class or interface 'System.Linq.IQueryable'
102961 次浏览

尝试添加.ToList () ;

var listOppLineData = (from o in db.opportunity_vws
where o.fiscal_yr_and_qtr == qtr
select o
).ToList();

更新

并修复查询。

如果没有.ToList () ,您将无法迭代任何内容;

头出臀部更新

var listOppLineData = (from o in db.opportunity_vws
where (whichGroup == "All" || o.Group == whichGroup)
&& (o.fiscal_yr_and_qtr == qtr)
select o);

把你的“空头”放在手术室之前,这样如果不需要的话,第二部分就不会被评估。我还是会用。但是 ToList ()。

试试这个:

IQueryable<opportunity_vw> listOppLineData;

这是在定义变量,但是您正在等待初始化它。

另外,查看您的查询,您可以一次完成所有操作,如下所示:

var listOppLineData = (from o in db.opportunity_vws
where o.fiscal_yr_and_qtr == qtr && (o.Group == whichGroup || whichGroup == "All")
select o
);

您的问题是,当您在 C # 中声明一个变量时,您只能在当前范围中声明它。因此,如果在 if块中声明变量 listOppLineData,那么只能在该块中使用它,而不能在其他任何地方使用它。(您可以在另一个块中定义另一个具有相同名称的变量,但它将是一个完全不同的变量,因此它不具有分配给第一个变量的值。)

正如您已经指出的,您需要在 if块之外声明变量。

您的第一次尝试没有成功,因为编译器发现您没有显式地指定变量的类型(var就是这样做的) ,并且您为变量分配了一个 string。所以它推断变量的类型是 string。你不能把不是 string的东西赋给这样的变量。

您的第二次尝试不起作用,因为您无法创建接口的实例。(如果您想创建一个实例,它必须是某种特定的类型,通常是一个类。)即使你修正了这个问题,非通用 IQueryable也不知道其中的项目类型,所以 foreach不会工作得很好。

但是您不需要为变量赋任何值,因为它是在 if的两个分支中赋值的。这里正确的类型是通用 IQueryable<T>Topportunity_vw。这意味着正确的代码是:

IQueryable<opportunity_vw> listOppLineData;


if (whichGroup == "All")
{
listOppLineData = …;
}
else
{
listOppLineData = …;
}


foreach (var data in listOppLineData)
{
…
}

如果您真的想为变量赋值(尽管这里没有理由这样做) ,可以使用 null(它表示没有值) :

IQueryable<opportunity_vw> listOppLineData = null;

试试这个。通过用类型名称替换 T,可以用 T或特定类型创建泛型类型。

IQueryable listOppLineData = Enumerable.Empty<T>().AsQueryable()

您可以像这样使用声明:

var listOppLineData = (object)null;

然后使用这个变量:

listOppLineData = (from o in db.opportunity_vws
where o.fiscal_yr_and_qtr == qtr && (o.Group == whichGroup || whichGroup == "All")
select o
);

对我来说,答案是从现有的查询中设置为空,并且如果它被转换为可枚举的,那么可以毫无例外地调用 sync:

query1 = query1.Take(0);

它用于在一个公共对象中联合来自不同表的2个查询,在某些验证情况下,其中一个查询可能变为空。如果我将第一个查询从 union 移动到 Enumable,那么当调用 union 时,如果使用异步函数(ToListAsync ())调用它,我将得到异常:

var res = (await query1
.Select(q1=> new NewClass(q1))
.ToListAsync())
.Union(query2
.Select(q2=> new NewClass(q2)))
.ToList();