【发布时间】:2019-04-10 22:45:29
【问题描述】:
在带有 Entity Framework Core 的 ASP.NET Core 应用程序中,会显示记录列表。因此,将获取集合的所有实体并将它们的一些属性显示在表格中。
此外,还有通过外键连接的相关实体。对于其中一些,还应显示对象的总数。
例如有以下表格(简体):
- 位置(ID、姓名、地址)
- 设备(ID、名称、评论、LocationId)
这里只显示位置(主要实体)和设备(相关实体),但除了设备之外还有更多类型。数据库中的所有设备都分配到一个位置。实体类中存在外键和导航属性,以及非映射计数属性(参见最后一个示例)。
想要的结果是这样的:
- 位置 ID 1,名称 1,此位置有 15 个设备
- 位置 ID 2,名称 2,此位置有 6 个设备
- 位置 ID 3,名称 3,0 个设备在此位置
我可以先获取按名称排序的位置,然后在单独的数据库查询中获取每个位置的设备数量。这可能会导致大量短查询。
var locations = dbContext.Locations
.OrderBy(l => l.Name)
.ToList();
foreach (var location in locations)
{
int count = dbContext.Devices.Where(d => d.LocationId == location.Id).Count();
}
我还可以使用Include(location => location.Devices) 获取所有位置,然后只使用location.Devices.Count 获取它们的计数,但这涉及获取所有设备的所有详细信息,最终只使用它们的总计数。
var locations = dbContext.Locations
.Include(l => l.Devices)
.OrderBy(l => l.Name)
.ToList();
foreach (var location in locations)
{
int count = location.Devices.Count;
}
我可以像往常一样首先获取所有位置,然后构建一个查询来收集所有位置的设备计数。然后我必须通过遍历一个列表并在另一个列表中找到相应的条目来手动合并这些结果集,这可能会导致大量内存搜索。
var locations = dbContext.Locations
.OrderBy(l => l.Name)
.ToList();
var deviceCounts = dbContext.Locations
.Select(l => new
{
l.Id,
l.Devices.Count
});
foreach (var c in deviceCounts)
{
locations.First(l => l.Id == c.Id).DeviceCount = c.Count;
}
我正在寻找一个查询来获取按名称排序的位置以及每个位置的设备计数。结果必须是我的实体类型的列表,例如List<Location>。是否有一种简单或有效的方法可以通过 EF Core 实现这一目标?
【问题讨论】:
-
context.Query<LocationsWithDevicesCount>().FromSql("SELECT L.Id, L.Name, L.Address, Count(1) DevicesCount FROM Locations L LEFT OUTER JOIN Devices D ON L.Id = D.LocationId ORDER BY L.Name").AsNoTracking().ToList().
标签: c# .net entity-framework-core