我正在注意EF6 Code First,我有5个表/实体,具有多对多关系,如下所示:
[Table("TableA")]
public class TableA {
public Guid Id { get; set; }
public string PropA { get; set; }
}
[Table("TableB")]
public class TableB {
public Guid Id { get; set; }
public string PropB { get; set; }
}
[Table("TableC")]
public class TableC {
public Guid Id { get; set; }
public string PropC { get; set; }
}
[Table("TableAB")]
public class TableAB {
[ForeignKey("TableA")]
public Guid TableAId { get; set; }
public TableA { get; set; }
[ForeignKey("TableB")]
public Guid TableBId { get; set; }
public TableB { get; set; }
}
[Table("TableBC")]
public class TableBC {
[ForeignKey("TableB")]
public Guid TableBId { get; set; }
public TableB { get; set; }
[ForeignKey("TableC")]
public Guid TableCId { get; set; }
public TableC { get; set; }
}
我正在寻找使用linq实体并获得一个“树”对象,如下所示,而不使用导航:
new List<A_DTO>() {
Id: ...
PropA: ...
B: new List<B_DTO>(){
Id: ...
PropB: ...
C: new List<C_DTO>(){
Id: ...
PropC: ...
}
}
}
我遇到的另一个问题是在某些情况下A和B或B和C之间不存在记录,这就是我使用左连接的原因。 我尝试了什么,它看起来非常混乱,不确定它是否按预期工作:
from a in Repository.All<TableA>()
join abT in Repository.All<TableAB>() on a.Id equals abT.TableAId into abTemp
from ab in abTemp.DefaultIfEmpty()
join bT in Repository.All<TableB>() on ab.TableBId equals bT.Id into bTemp
from b in bTemp.DefaultIfEmpty()
join abT in Repository.All<TableBC>() on b.Id equals bcT.TableBId into bcTemp
from bc in bcTemp.DefaultIfEmpty()
join cT in Repository.All<TableC>() on bc.TableCId equals cT.Id into cTemp
from c in bTemp.DefaultIfEmpty()
select new A_DTO(){
Id: a.Id,
PropA: a.PropA,
B: abTemp.Select(_ab => new B_DTO(){
Id: _ab.B.Id, // what if _ab.B is null?
PropB: _ab.B.PropB,
C: bcTemp.Select(_bc => new C_DTO(){
Id: _bc.C.Id, // what if _bc.C is null?
PropC: _bc.C.PropC
}
}
}
有没有办法以更简单/愉快的方式做到这一点?
谢谢!
答案 0 :(得分:0)
我认为这应该有效(这告诉EF不要对B和B.C使用延迟加载,因此包括对象):
Repository.All()<TableA>().Include(x => x.B).Include(x => x.B.C)
默认情况下,所有相关对象都是虚拟属性,并视为延迟加载。您不需要对对象的属性执行此操作,因此只需包含B属性即可包含a.propa和a.b.propa。