我正在使用带有ASP.NET MVC 3的Entity Framework 4.1。我有两个表与一对多的关系,假设购物和 ShopVisit ,我希望以访问次数显示商店列表。作为SQL查询非常简单,但如何让Entity Framework有效地执行此操作?
这有效:
_db.Shops.Include("Visits").ToList();
@foreach (var shop in ViewBag.Shops)
{
Visit count: @shop.Visits.Count
}
然而,看看SQL Profiler,它似乎是使用LEFT OUTER JOIN加载所有访问,这不是我想要的。我只想要伯爵。当然,我也不希望每个商店都进行子查询。我该怎么做才能进行COUNT(*) ... GROUP BY
查询?
即使我选择这样的选择:
_db.Shops.Include("Visits").Select(s => ShopStats { Shop = s, Vists = s.Vists.Count}).ToList();
它仍然坚持做一个LEFT OUTER JOIN,它会加载所有访问。
答案 0 :(得分:1)
在这种情况下,您需要创建自定义类型并使用投影:
var data = from s in _db.Shops
select new SomeCustomType
{
Shop = s,
Count = s.Visits.Count()
};
您还可以展平SomeCustomType
,以便它包含Shop
的所有属性,而不是商店本身。它可能会在查询内部进行左外连接,但不会加载对应用程序的访问。
包含或延迟加载如您所述 - 计数将在内存中计算,因此必须加载所有访问。
修改强>
还有一种称为延迟加载的解决方案。它不是开箱即用的,而是you can extend EF to support it。如果是延迟加载,您将无法加载Visits
,但Count
将触发查询到数据库以获取访问次数。