Linq to SQL立即执行查询

3

我有一个Linq查询想要立即执行,然后操作数据。现在在下面的代码中,当第二个(2) Linq查询执行时,第一个(1) Linq查询已经被执行了。我想先执行第一个(1)查询,怎么做呢?

// 1
var statistic = DataAccess.Instance.Statistics
                    .Where(p => p.DateStamp >= fromDate && p.DateStamp <= DateTime.UtcNow && p.UserId == userId)
                    .Select(p => new {p.DateStamp.Year, p.DateStamp.Month, p.DateStamp.Day });


values = new int[interval];
labels = new string[interval];

for (var i = 0; i < labels.Length; i++)
{
    // 2
    var recordsCount = statistic.Count(p => p.Year == dayStep.Year && p.Month == dayStep.Month && p.Day == dayStep.Day);
}
3个回答

9

我认为您在.NET数据操作中错过了一个重要的概念。

延迟和立即获取

值得强调的一点是,默认情况下,LINQ to SQL仅在您请求数据时从数据库检索数据,而不是在定义LINQ to SQL查询或创建Table集合时检索。这被称为延迟获取。

当foreach循环开始时,LINQ to SQL创建并运行一个SQL SELECT语句来创建一个ADO.NET DataReader对象。每次迭代foreach循环都执行必要的GetXXX方法以获取该行的数据。在foreach循环处理完最后一行后,LINQ to SQL关闭数据库连接。

延迟获取确保只有应用程序实际使用的数据才从数据库中检索。但是,如果您正在访问运行在远程SQL Server实例上的数据库,则逐行获取数据并不会充分利用网络带宽。在这种情况下,您可以通过强制立即评估LINQ to SQL查询来一次性获取和缓存所有数据。您可以通过调用ToList或ToArray扩展方法来实现这一点,这将在您定义LINQ to SQL查询时将数据获取到列表或数组中,如下所示:

var productsQuery = from p in products.ToList()
select p;

我没有错过任何东西。我询问如何先执行数据,然后进行其他操作,因为我了解Linq的工作原理 :) 无论如何,感谢您详细的描述! - Tomas
@PankajUpadhyay 这个 var productsQuery = (from p in products select p.ToList(); 和你的示例代码一样吗?如果不是,如果我在你的示例中添加一个 where 子句,它会只获取与 where 子句匹配的结果吗? - Igor
@Igor 是的,你也可以使用 where。 - Pankaj Upadhyay

3

尝试这个第一条语句(注意 .ToList() 语句)

var statistic = DataAccess.Instance.Statistics.Where(p => p.DateStamp >= fromDate && p.DateStamp <= DateTime.UtcNow && p.UserId == userId).
                Select(p => new {p.DateStamp.Year, p.DateStamp.Month, p.DateStamp.Day }).ToList();

2
你可以使用类似于.ToList()的方法来强制执行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接