实例化空 IQueryable 以与 Linq to sql 一起使用

问题描述 投票:0回答:7

我需要能够在 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'
c# asp.net-mvc linq linq-to-sql iqueryable
7个回答
256
投票

试试这个。您可以使用 T 创建通用类型,也可以通过将 T 替换为您的类型名称来创建特定类型。

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

39
投票

试试这个:

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
                      );

7
投票

您的问题是,当您在 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;

4
投票

对我来说,答案是从现有查询中设置为空,并且如果转换为可枚举,则能够毫无例外地调用 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();

0
投票

.AsQueryable() 就是您寻求的答案。我们可以单独使用这些 IEnumerables 将这些 IEnumerables 转换为 IQueryables。

IQueryable<T> myQueryable = new List<T>() { new T() { TProp1 = 1, TProp2 = 2} }.AsQueryable(); 

-1
投票

尝试添加 .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() 。


-3
投票

您可以使用这样的声明:

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
);
© www.soinside.com 2019 - 2024. All rights reserved.