我在理解 IQueryable时遇到问题

发布于 2024-09-10 00:49:52 字数 415 浏览 2 评论 0原文

所以我试图理解IQueryable。我正在阅读的教程建议使用它,但不太确定为什么。该代码只是使用 LINQ to SQL 返回一些值。我过去曾多次这样做过,但没有使用 IQueryable

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

这是我的代码:

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

So I'm trying to understand IQueryable<T>. A tutorial I'm reading suggests using it but not really sure why. The code simply returns some values using LINQ to SQL. I've done this plenty of times in the past, but not using IQueryable<T>

Why use it with my functions that return more than 1 value?

Here's my code:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

白衬杉格子梦 2024-09-17 00:49:52

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.
}

在我们尝试使用以下结果之前,不会向服务器发送任何内容foreach 循环。此时,LINQ-to-SQL 提供程序会评估整个表达式,包括在 GetItems() 内部生成的位以及后面指定的位,并发出一个 SQL 语句,该语句选择同时满足以下条件的所有项目:活跃且最近。

为了澄清技术细节,IQueryable 是一个 IEnumerable,当您尝试调用 GetEnumerator() 时,它的提供程序会计算最终的 SQL 方法就可以了。您可以通过调用显式地执行此操作,也可以通过在 foreach 语句中使用它来隐式地执行此操作。此外,诸如 ToArray() 之类的扩展方法将在内部执行其中一项操作,从而产生相同的效果。

IQueryable represents the query as an expression tree without evaluating it on the server. This lets you specify further processing before actually generating SQL.

In the above case, this means that you can do stuff with the result of calling GetItems(), and have the original query and the extra stuff sent as a single query:

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

foreach (var item in recentItems)
{
    // Do something with an active recent item.
}

Nothing is sent to the server until we try to consume the result in the foreach loop. At that point, the LINQ-to-SQL provider assesses the entire expression, including the bits generated inside GetItems() and the bits specified after, and emits a single SQL statement that selects all items that are both active and recent.

To clarify a technicality, the IQueryable<T> is an IEnumerable<T>, and its provider computes the final SQL when you try to invoke the GetEnumerator() method on it. You can either do this explicitly by calling it, or implicitly by using it in a foreach statement. Also, extension methods like ToArray() will do one of these internally, thus producing the same effect.

软甜啾 2024-09-17 00:49:52

IQueryable(在枚举之前)不是结果本身,而是用于返回这些结果的逻辑。

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

SELECT * FROM [Clients]

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

var clients = GetClients().Where(c => c.Name == "Bob");

现在 IQueriable 在幕后看起来像这样:

SELECT * FROM [Clients] WHERE Name = 'Bob'.

现在,当我执行 client.ToList() 时,该查询将运行,数据库被命中,并且我有一个名为 bob 的客户端列表,而不必选择所有客户端,然后在内存中搜索它们,或执行 2 个单独的数据库命中。

举个例子,当你的数据上下文超出范围时,你会在后面尝试获取子元素(例如:在 using 语句中运行你的选择)。这就是 LINQ2SQL 中加载选项派上用场的地方。

希望有帮助

An IQueryable (before it is enumerated) is not the results them selves but the logic used to return those results.

To use a LINQ2SQL example... imagine you return an IQueryable of Clients.
Under the hood that will not be a list of clients (until you ToList() it) but will actualy be a SQL Query like so:

SELECT * FROM [Clients]

Now this is handy because we have not hit the database yet! So lets say when that IQueriable comes back we want to refine it down to Clients called "Bob" we can do:

var clients = GetClients().Where(c => c.Name == "Bob");

Now the IQueriable looks like this under the hood:

SELECT * FROM [Clients] WHERE Name = 'Bob'.

Now when I do clients.ToList(), that query will run, the database is hit, and I have a list of clients called bob without having to have selected all clients then trawl through them in memory, or perform 2 separate database hits.

For an example of this biting you in the behind try and get to child elements when your datacontext has dropped out of scope(e.g: run your select inside a using statement). This is where load options come in handy, in LINQ2SQL.

Hope that helps

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文