试图找出 Entity Framework 中的查询何时执行
Trying to figure out when queries in Entity Framework are executed
这是我第一次使用 Entity Framework (EF),我正在尝试了解究竟是什么在我的数据库上执行查询,什么不是。
这是我正在使用的代码。不要介意功能,这个问题不重要。
using (var db = new Context())
{
//Check if any reviews have been given.
if (combinedReviews.Any())
{
var restaurantsReviewedIds = combinedReviews.Select(rev => rev.RestaurantId);
//(1)
ratedRestaurants = db.Restaurants.Where(rest => restaurantsReviewedIds.Contains(rest.Id))
.DistinctBy(rest => rest.Id)
.ToList();
}
//(2)
var restsClose = db.Restaurants.Where(rest => db.Reviews.Any(rev => rev.RestaurantId == rest.Id))
.OrderBy(rest => rest.Location.Distance(algorithmParams.Location))
.Take(algorithmParams.AmountOfRecommendations);
//(3)
tempList = ratedRestaurants.Union(restsClose).ToList();
var tempListIds = tempList.Select(rest => rest.Id); //Temporary list.
//(4)
restsWithAverage = db.Reviews.Where(rev => tempListIds.Contains(rev.RestaurantId))
.GroupBy(rev => rev.RestaurantId)
.ToList();
}
我已经用数字标记了每段代码,所以我会用它来引用它们。以下是我认为会发生什么。
这会执行一个查询,因为我在这里调用 .ToList()
。
这个 returns 一个 IQueryable
,所以这不会对数据库执行查询。
这会执行来自 (2) 的查询。
这会执行另一个查询,因为我正在调用 .ToList()
。
我离真相有多近?这些都是正确的吗?如果这没有意义,你能举例说明什么执行查询,什么不执行查询吗?
很抱歉在一个问题中问了这么多问题,但我认为我不需要创建这么多问题,因为所有这些都是关于一个主题的。
Linq 查询执行因查询而异。我建议阅读以下页面:https://msdn.microsoft.com/en-us/library/bb738633(v=vs.110).aspx
如果您不想执行查询,您可以使用 AsEnumerable
.
ToList
对比 AsEnumerable
ToList
– 将 IEnumerable<T>
转换为 List<T>
。使用 AsEnumerable
与 ToList
的优点是 AsEnumerable
不执行查询。 AsEnumerable
保留延迟执行并且不构建通常无用的中间列表。
另一方面,当需要强制执行 LINQ 查询时,ToList
可能是一种方法。
您还可以通过在查询表达式之后立即放置一个 For Each 循环来强制执行,但是通过调用 ToList 或 ToArray,您可以将所有数据缓存在一个集合对象中。
ToLookup
和 ToDictionary
也在执行查询。
在这里您可以找到运算符列表以及它们是否正在执行查询:
https://msdn.microsoft.com/en-us/library/mt693095.aspx.
这是我第一次使用 Entity Framework (EF),我正在尝试了解究竟是什么在我的数据库上执行查询,什么不是。
这是我正在使用的代码。不要介意功能,这个问题不重要。
using (var db = new Context())
{
//Check if any reviews have been given.
if (combinedReviews.Any())
{
var restaurantsReviewedIds = combinedReviews.Select(rev => rev.RestaurantId);
//(1)
ratedRestaurants = db.Restaurants.Where(rest => restaurantsReviewedIds.Contains(rest.Id))
.DistinctBy(rest => rest.Id)
.ToList();
}
//(2)
var restsClose = db.Restaurants.Where(rest => db.Reviews.Any(rev => rev.RestaurantId == rest.Id))
.OrderBy(rest => rest.Location.Distance(algorithmParams.Location))
.Take(algorithmParams.AmountOfRecommendations);
//(3)
tempList = ratedRestaurants.Union(restsClose).ToList();
var tempListIds = tempList.Select(rest => rest.Id); //Temporary list.
//(4)
restsWithAverage = db.Reviews.Where(rev => tempListIds.Contains(rev.RestaurantId))
.GroupBy(rev => rev.RestaurantId)
.ToList();
}
我已经用数字标记了每段代码,所以我会用它来引用它们。以下是我认为会发生什么。
这会执行一个查询,因为我在这里调用
.ToList()
。这个 returns 一个
IQueryable
,所以这不会对数据库执行查询。这会执行来自 (2) 的查询。
这会执行另一个查询,因为我正在调用
.ToList()
。
我离真相有多近?这些都是正确的吗?如果这没有意义,你能举例说明什么执行查询,什么不执行查询吗?
很抱歉在一个问题中问了这么多问题,但我认为我不需要创建这么多问题,因为所有这些都是关于一个主题的。
Linq 查询执行因查询而异。我建议阅读以下页面:https://msdn.microsoft.com/en-us/library/bb738633(v=vs.110).aspx
如果您不想执行查询,您可以使用 AsEnumerable
.
ToList
对比 AsEnumerable
ToList
– 将 IEnumerable<T>
转换为 List<T>
。使用 AsEnumerable
与 ToList
的优点是 AsEnumerable
不执行查询。 AsEnumerable
保留延迟执行并且不构建通常无用的中间列表。
另一方面,当需要强制执行 LINQ 查询时,ToList
可能是一种方法。
您还可以通过在查询表达式之后立即放置一个 For Each 循环来强制执行,但是通过调用 ToList 或 ToArray,您可以将所有数据缓存在一个集合对象中。
ToLookup
和 ToDictionary
也在执行查询。
在这里您可以找到运算符列表以及它们是否正在执行查询: https://msdn.microsoft.com/en-us/library/mt693095.aspx.