我需要能够在 Linq 查询中拥有可选参数,或者能够将查询分配给 IF 之类的 var(如果需要从查询中删除该可选参数)。
如果我在 IF 语句中设置查询 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'
试试这个。您可以使用 T 创建通用类型,也可以通过将 T 替换为您的类型名称来创建特定类型。
IQueryable listOppLineData = Enumerable.Empty<T>().AsQueryable();
试试这个:
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# 中声明变量时,您仅在当前范围内声明它。因此,如果您在
listOppLineData
块中声明变量 if
,则只能在该块内使用它,而不能在其他任何地方使用它。 (您可以在另一个块中定义另一个具有相同名称的变量,但这将是一个完全不同的变量,因此它不会具有您分配给第一个变量的值。)
正如您已经想到的,您需要在
if
块之外声明变量。
您的第一次尝试没有成功,因为编译器发现您没有显式指定变量的类型(这就是
var
的作用),并且您为该变量分配了 string
。所以推断变量的类型是string
。并且您不能将不是 string
的内容分配给此类变量。
您的第二次尝试没有成功,因为您无法创建接口的实例。 (如果你想创建一个实例,它必须是某种特定的类型,通常是一个类。)即使你修复了这个问题,非泛型
IQueryable
也不知道其中的项目类型,所以 foreach
效果不太好。
但是您不需要为变量分配任何值,因为它是在
if
的两个分支中分配的。这里正确的类型是通用 IQueryable<T>
,其中 T
是 opportunity_vw
。这意味着正确的代码是:
IQueryable<opportunity_vw> listOppLineData;
if (whichGroup == "All")
{
listOppLineData = …;
}
else
{
listOppLineData = …;
}
foreach (var data in listOppLineData)
{
…
}
如果您确实想为变量分配一些值(尽管这里没有理由这样做),您可以使用
null
(表示没有值):
IQueryable<opportunity_vw> listOppLineData = null;
对我来说,答案是从现有查询中设置为空,并且如果转换为可枚举,则能够毫无例外地调用 async :
query1 = query1.Take(0);
它用于将来自不同表的 2 个查询合并到一个公共对象中,其中一个查询在某些验证情况下可能会变为空。如果我将第一个查询从联合移动到可枚举,如果在调用联合时使用异步函数(ToListAsync())调用它,我将得到异常:
var res = (await query1
.Select(q1=> new NewClass(q1))
.ToListAsync())
.Union(query2
.Select(q2=> new NewClass(q2)))
.ToList();
.AsQueryable() 就是您寻求的答案。我们可以单独使用这些 IEnumerables 将这些 IEnumerables 转换为 IQueryables。
IQueryable<T> myQueryable = new List<T>() { new T() { TProp1 = 1, TProp2 = 2} }.AsQueryable();
尝试添加 .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);
将“short”放在 OR 之前,这样如果不需要,就不会评估第二部分。不过我仍然会使用 .ToList() 。
您可以使用这样的声明:
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
);