【问题标题】:Linq Query reuseLinq 查询重用
【发布时间】:2013-11-10 05:33:44
【问题描述】:

我有一个 Linq 查询,它从 SQL Server 返回大量结果,我想确保我从数据库中获取一次记录,然后简单地在页面内按需循环遍历记录而无需访问数据库。

这是一个简单的查询:

Dim c1 = (From c2 In _db.CategoryRelationShip
        Select c2)

现在我在页面的某个地方:

For Each item In c1

Next

然后又一次:

For Each item In c1

Next

这是否意味着在每个 For 循环中,我都会一次又一次地访问数据库?还是我的原始 Linq 检索了所有记录,而我只是循环遍历数组/结果?

我听说过 toList() 方法,所以我很困惑我是否需要它?...我的意思是如果我这样做:

Dim c1 = (From c2 In _db.CategoryRelationShip
        Select c2).toList()

【问题讨论】:

    标签: asp.net-mvc vb.net linq entity-framework


    【解决方案1】:

    LINQ 使用延迟执行,这意味着在您需要数据之前不会评估任何内容。本声明:

    Dim c1 = (From c2 In _db.CategoryRelationShip
              Select c2)
    

    不从数据库中获取任何数据。正如 Gert Arnold 在 cmets 中对另一个答案所说:

    c1 只是一个等待发生的查询(延迟执行)。

    所以是的。如果您只是遍历c1,您将执行两次查询。您可以轻松验证这一点:

    Dim myCollection As New List(Of Integer)(New () {1, 2})
    
    Dim result = (From c In myCollection
                  Select c)
    
    For Each i As Integer In result
        Console.WriteLine(i)    ' Will print 1 and 2
    Next
    
    myCollection.Add(3)
    Console.WriteLine()
    
    For Each i As Integer In result
        Console.WriteLine(i)    ' Will print 1, 2 and 3
    Next
    

    你可以对你的数据库做同样的测试。

    为避免两次调用数据库,您可以使用.ToList(),它将“强制”评估查询并将结果存储在列表中。如果您在上面的示例中将(From c In myCollection Select c) 替换为(From c In myCollectionc Select c).ToList(),您将打印两次 1 和 2。

    【讨论】:

    • 很好,有什么不同......我的页面运行得更快......所以如果我调用“.Take(10)”或“.SingleorDefault”或“.Count”.. ..他们会立即执行查询吗?
    • @highwingers 弄清楚会发生什么的最好方法是尝试一下。 SingleOrDefaultCount 会立即执行,而 Take 不会。如果一个方法返回单个值,它很可能不会使用延迟执行。
    猜你喜欢
    • 2016-03-24
    • 1970-01-01
    • 2016-02-08
    • 1970-01-01
    • 1970-01-01
    • 2011-11-26
    • 2013-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多