【发布时间】:2018-10-02 12:47:10
【问题描述】:
假设我们有一个简单的 one->one->many 关系与下表结构:
public class City
{
public string Name { get; set; }
[Column("DtaCentralSchoolId")]
[ForeignKey("MyCentralSchool")]
public int? CentralSchoolId { get; set; }
public CentralSchool MyCentralSchool { get; set; }
}
public class CentralSchool
{
public string Name { get; set; }
[InverseProperty("MyCentralSchool")]
public virtual IList<Student> MyStudents { get; set; }
}
public class Student
{
public string Name { get; set; }
[Column("DtaCentralSchoolId")]
[ForeignKey("MyCentralSchool")]
public int? CentralSchoolId { get; set; }
public CentralSchool MyCentralSchool { get; set; }
}
并尝试运行以下查询:
var result = await dbContext.Set<City>()
.AsNoTracking()
.SelectMany(x => x.MyCentralSchool.MyStudents.DefaultIfEmpty(), (c, s) => new {City = c, Student = s})
.Where(x => x.Student == null || !x.Student.IsDeleted && x.Student.MyStoreId == storeId)
.FirstOrDefaultAsync();
因此,出于某种原因,CentralSchool INNER JOIN 正在生成,而 Student 则有 LEFT JOIN,就 而言这完全没问题使用 DefaultIfEmpty()。 实际上,我也希望 CentralSchool 的 LEFT JOIN ,所以当没有 CentralSchool 时,无论如何都会有一些行出现在结果中,如何在当前构造中实现这一点,而无需手动重写丑陋的查询并强制 LEFT JOIN 出现?
更新
问题已解决,修复将在2.2中发布:
https://github.com/aspnet/EntityFrameworkCore/issues/13511
【问题讨论】:
-
您正在尝试检索学生,而不是城市。您可能应该反转查询并在每个学生中包含学校和城市,或者选择学生和相应的城市,例如
.Set<Students>().Where(s=>!s.IsDeleted && s.MyStoreId==storeId).Select(s=>new {Student=s,City=student.MyCentralSchool.City});。对于 this 查询,应该有City属性的是 School,而不是相反。如果您需要以两种方式访问对象,则它们应该通过适当的配置相互引用 -
@PanagiotisKanavos,对不起,如果有的话,我正在尝试准确地检索有学生的城市。这个表结构只是我用来描述问题的结构,这里的问题更具体地是关于 EF 行为,而不是关于业务逻辑。
标签: entity-framework linq entity-framework-6 entity-framework-core ef-fluent-api