C# 如何使用linq for entities或EF Core 2从子级到父级选择层次结构?
有四个实体(模型)的层次结构。所有实体都有一对多的关系。它看起来如下:C# 如何使用linq for entities或EF Core 2从子级到父级选择层次结构?,c#,linq,entity-framework-core,parent-child,C#,Linq,Entity Framework Core,Parent Child,有四个实体(模型)的层次结构。所有实体都有一对多的关系。它看起来如下: public class Region { public Guid Id { get; set; } public int RegionId { get; set; } public virtual ICollection<District> Districts { get; set; } } public class District
public class Region
{
public Guid Id { get; set; }
public int RegionId { get; set; }
public virtual ICollection<District> Districts { get; set; }
}
public class District
{
public Guid Id { get; set; }
public int DistrictId { get; set; }
public virtual ICollection<Building> Buildings { get; set; }
public int RegionId { get; set; }
public Region Region { get; set; }
}
public class Building
{
public Guid Id { get; set; }
public int BuildingId { get; set; }
public int DistrictId { get; set; }
public virtual ICollection<Flat> Flats { get; set; }
public District District { get; set; }
}
public class Flat
{
public Guid Id { get; set; }
public int FlatId { get; set; }
public int BuildingId { get; set; }
public Building Building { get; set; }
}
但由于某种原因,这是回报突破的结果
[{"id":"6cbb1431-36d4-490c-a047-c211e4db3bdd","flatId":29570,"roomsCount":1,"totalArea":41.95,"kitchenArea":11.85,"floor":21,"buildingId":130,"price":5725650.00,"building":{"id":"03baca1e-02e9-4ee0-ae47-920e3eb0d5bb","buildingId":130,"name":"NNN","queue":1,"housing":"1","districtId":13003,"flats":[
它在公共虚拟ICollection Flats{get;set;}
上由于某种原因而中断。我不能移除它,因为它是FK需要的
以下查询工作正常:
_context.Flat
.Join(
_context.Building,
f => f.BuildingId,
b => b.BuildingId,
(f, b) =>
new
{
f = f,
b = b
}
)
.Join(
_context.District,
temp0 => temp0.b.DistrictId,
d => d.DistrictId,
(temp0, d) =>
new
{
temp0 = temp0,
d = d
}
)
.Join(
_context.Region,
temp1 => temp1.d.RegionId,
r => r.RegionId,
(temp1, r) =>
new
{
Id = temp1.temp0.f.Id,
FlatId = temp1.temp0.f.FlatId,
Floor = temp1.temp0.f.Floor,
RoomsCount = temp1.temp0.f.RoomsCount,
TotalArea = temp1.temp0.f.TotalArea,
KitchenArea = temp1.temp0.f.KitchenArea,
Price = temp1.temp0.f.Price,
Building = new
{
Id = temp1.temp0.b.Id,
BuildingId = temp1.temp0.b.Id,
Name = temp1.temp0.b.Name,
Queue = temp1.temp0.b.Queue,
Housing = temp1.temp0.b.Housing,
District = new
{
Id = temp1.d.Id,
DistrictId = temp1.d.DistrictId,
Name = temp1.d.Name,
Regions = new
{
Id = r.Id,
RegionId = r.Id,
Name = r.Name
}
}
}
}
).GetPaged(PageNumber, PageSize)
这是我想要的回报:
{
"id": "a49a0a48-370b-46da-b6da-ea4040cc1431",
"flatId": 84095,
"roomsCount": 3,
"totalArea": 76.5,
"kitchenArea": 11.07,
"floor": 18,
"buildingId": 0,
"price": 5567500,
"building": {
"id": "037c4074-3ff5-4fbd-92ea-88c8f746b883",
"buildingId": 200,
"name": "NNNN",
"queue": 3,
"housing": "4",
"districtId": 0,
"flats": null,
"district": {
"id": "db031e09-1d6c-41f4-9e45-ec6170e3df8b",
"districtId": 5005,
"name": "Distr",
"buildings": null,
"regionId": 0,
"region": {
"id": "5ac5766f-e62e-4da9-86cf-e4a85423503a",
"regionId": 5001,
"name": "Region",
"districts": null
}
}
}
}
但它看起来很笨重。
我如何使用EF功能实现这一点?或者是为了降低linq?为什么include()
返回中断结果
p.S.
.GetPaged(页码,20)
是分页的扩展方法,他工作得很好。我的建议如下
var flag = (from f in _context.Flags
join b in _context.Buildings
on b.BuildingId equals f.BuildingId
join d in _context.Districts
on d.DistrictId equals b.DistrictId
join r in _context.Regions
on r.RegionId equals d.RegionId
select new
{ ...
}).GetPaged(PageNumber, 20);
您可以从Building、District和Region中获取任何属性以填充到结果对象中。下面是我的建议
var flag = (from f in _context.Flags
join b in _context.Buildings
on b.BuildingId equals f.BuildingId
join d in _context.Districts
on d.DistrictId equals b.DistrictId
join r in _context.Regions
on r.RegionId equals d.RegionId
select new
{ ...
}).GetPaged(PageNumber, 20);
您可以从Building、District和Region中获取任何属性以填充到结果对象。每个建筑只有一个District和一个Region,为什么不添加District=f.Building.District,Region=f.Building.District.Region?我不能仅仅添加,因为通过这个模型,EF代码首先生成数据库。不清楚实际的问题是什么
Include
query很好,不确定“它工作得很慢”是什么意思。您是否测量了EF查询执行时间?生成的SQL?最后,JSON序列化中可能会出现问题(如果有)。在尝试使用冗余连接和投影解决问题之前,先将问题本地化。我已更正了文本。请参见上文。@Seva,对于Include方法,我认为您应该为结果创建一个动态类。每个建筑只有一个地区和一个区域,为什么不添加District=f.Building.District,Region=f.Building.District.Region?我不能仅仅添加,因为通过这个模型,EF代码首先生成数据库。不清楚实际的问题是什么Include
query很好,不确定“它工作得很慢”是什么意思。您是否测量了EF查询执行时间?生成的SQL?最后,JSON序列化中可能会出现问题(如果有)。在尝试使用冗余连接和投影解决问题之前,先将问题本地化。我已更正了文本。请参见上文。@Seva,对于Include方法,我认为您应该为结果创建一个动态类。您已经显示了一个标准的LINQ连接查询。但在EF中,我们不使用连接,而是使用导航属性。因为b
是f.Building
,d
是b.District
,r
是d.Region
。和联接由EF基于模型元数据自动提供。因此,这相当于包含的原始查询。也许应该尝试一下,比较两种方法生成的SQL是否有任何差异。我只想说,我的查询方式可能是性能最好的方式。它很有效。非常感谢。我已经改正了课文。请参见上面。您已经展示了一个标准的LINQ连接查询。但在EF中,我们不使用连接,而是使用导航属性。因为b
是f.Building
,d
是b.District
,r
是d.Region
。和联接由EF基于模型元数据自动提供。因此,这相当于包含的原始查询。也许应该尝试一下,比较两种方法生成的SQL是否有任何差异。我只想说,我的查询方式可能是性能最好的方式。它很有效。非常感谢。我已经改正了课文。请看上面。