我在理解IQueryable <T>时遇到了问题

drp*_*ken 14 c# asp.net collections data-access-layer

所以我想了解一下IQueryable<T>.我正在阅读的教程建议使用它,但不确定为什么.代码只是使用LINQ to SQL返回一些值.我过去做了很多次,但没有使用IQueryable<T>

为什么在我的函数中使用它返回超过1的值?

这是我的代码:

public IQueryable<Items> GetItems()
    {
        return from item in db.Items
               where item.IsActive == true
               orderby item.ItemNumber
               select item;
    }
Run Code Online (Sandbox Code Playgroud)

Mar*_*tos 13

IQueryable将查询表示为表达式树,而不在服务器上对其进行评估.这使您可以在实际生成SQL之前指定进一步的处理.

在上面的例子中,这意味着您可以使用调用GetItems()的结果执行操作,并将原始查询和额外内容作为单个查询发送:

var recentItems = from item in GetItems()
                  where item.Timestamp > somedate
                  select item;

foreach (var item in recentItems)
{
    // Do something with an active recent item.
}
Run Code Online (Sandbox Code Playgroud)

在我们尝试在foreach循环中使用结果之前,没有任何内容发送到服务器.此时,LINQ-to-SQL提供程序会评估整个表达式,包括内部生成GetItems()的位和后面指定的位,并发出一个SQL语句,用于选择所有活动项和最近项.

为了阐明技术性,它IQueryable<T>是一个IEnumerable<T>,当它尝试GetEnumerator()在其上调用方法时,它的提供者计算最终的SQL .您可以通过调用它来显式地执行此操作,也可以通过在foreach语句中使用它来隐式执行此操作.此外,扩展方法ToArray()将在内部执行其中一个,从而产生相同的效果.


jdo*_*oig 5

IQueryable(在枚举之前)不是结果,而是用于返回结果的逻辑.

要使用LINQ2SQL示例...假设您返回一个IQueryable客户端.在不会是客户列表的引擎下(直到你ToList()它),但实际上将是一个SQL查询,如下所示:

SELECT * FROM [Clients]
Run Code Online (Sandbox Code Playgroud)

现在这很方便,因为我们还没有打到数据库!因此,假设当IQueriable返回时,我们希望将其优化为名为"Bob"的客户端,我们可以这样做:

var clients = GetClients().Where(c => c.Name == "Bob");
Run Code Online (Sandbox Code Playgroud)

现在IQueriable看起来像这样:

SELECT * FROM [Clients] WHERE Name = 'Bob'.
Run Code Online (Sandbox Code Playgroud)

现在,当我做clients.ToList(),该查询将运行,数据库被击中,我有客户名单叫鲍勃,而不必选择所有客户端,然后通过在内存中,拖网,或执行2个独立的数据库访问.

有一个例子,当你的datacontext退出范围时,你会在后面尝试并获取子元素(例如:在using语句中运行你的select).这是LINQ2SQL中负载选项派上用场的地方.

希望有所帮助