Per*_*ier 4 entity-framework entity-framework-core asp.net-core
我在EF Core 1.1.2中有一个在客户端评估的查询,想知道是否有更好的方法将其转换为sql?
查询:
from l in _ctx.Locations
join i in _ctx.Inventories on l.Id equals i.LocationId
join it in _ctx.Items on i.ItemId equals it.Id
where l.ProjectId == projectid
group i by new {l.Id, l.LHA} into il
select new InventoryLocations() {
Id= il.Key.Id,
LHA = il.Key.LHA,
FlaggedItems = il.Any(x=>x.Item != null && x.Item.Flagged)
}
Run Code Online (Sandbox Code Playgroud)
如果没有,我还有什么其他选择?
楷模:
public class Location
{
public Guid Id { get; set; }
[ForeignKey("Project")]
public Guid ProjectId { get; set; }
public Project Project {get; set; }
public string Name { get; set; }
public string LHA { get; set; }
[ForeignKey("ScanUser")]
public Guid? ScanUserId { get; set; }
public User ScanUser { get; set; }
[ForeignKey("CheckUser")]
public Guid? CheckUserId { get; set; }
public User CheckUser { get; set; }
[ForeignKey("GroupLeader")]
public Guid? GroupLeaderId { get; set; }
public User GroupLeader { get; set; }
public int State { get; set; }
}
public class Inventory
{
public Guid Id { get; set; }
[ForeignKey("Project")]
public Guid ProjectId { get; set; }
public Project Project {get; set; }
public string EANCode { get; set; }
[ForeignKey("Location")]
public Guid LocationId { get; set; }
public Location Location { get; set; }
public Double ScanQty { get; set; }
[ForeignKey("ScanUser")]
public Guid? ScanUserId { get; set; }
public User ScanUser { get; set; }
public DateTime? ScanDate { get; set; }
[ForeignKey("Item")]
public Guid? ItemId { get; set; }
public Item Item { get; set; }
[ForeignKey("InventoryTask")]
public Guid? InventoryTaskId { get; set; }
public InventoryTask InventoryTask { get; set; }
[ForeignKey("CheckUser")]
public Guid? CheckUserId { get; set; }
public User CheckUser { get; set; }
public DateTime? CheckDate { get; set; }
public Double PrevQty { get; set; }
}
public class Item
{
public Guid Id { get; set; }
[ForeignKey("Project")]
public Guid ProjectId { get; set; }
public Project Project {get; set; }
public string ItemNo { get; set; }
public string EANCode { get; set; }
public string Name { get; set; }
public Double Price { get; set; }
public bool Deleted { get; set; }
public DateTime ChangeTime { get; set; }
public Double BaseQty { get; set; }
public bool Flagged { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
当前(在传入的EF Core v.2.0中也是如此),GroupBy查询是在本地处理的,因此关键是尽可能避免查询。
您的查询似乎符合条件-无需先将数据集与联接相乘,然后再将其分组。
我注意到您在实体中仅使用参考导航属性和FK,基本上像数据库表记录和SQL。但是EF允许您还定义相应的集合导航属性,该属性使您可以从逻辑根目录开始查询,从而消除了联接和分组依据。
如果您从Location到定义导航属性Inventory
public class Location
{
// ...
public ICollection<Inventory> Inventories { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
那么等效查询可以很简单:
from loc in _ctx.Locations
where loc.ProjectId == projectid
select new InventoryLocations()
{
Id = loc.Id,
LHA = loc.LHA,
FlaggedItems = loc.Inventories.Any(inv => inv.Item != null && inv.Item.Flagged)
}
Run Code Online (Sandbox Code Playgroud)
它将完全转换为SQL。
如果由于某种原因您无法创建上述集合导航属性,则仍然可以从位置开始并将它们与库存手动关联:
from loc in _ctx.Locations
where loc.ProjectId == projectid
select new InventoryLocations()
{
Id = loc.Id,
LHA = loc.LHA,
FlaggedItems = _ctx.Inventories.Any(inv => loc.Id == inv.LocationId && inv.Item != null && inv.Item.Flagged)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15286 次 |
| 最近记录: |