我正在使用EF Core 3.1.3,并且有以下两个查询:
var test = await _unitOfWork.Context.PersonEmail
.OrderBy(e => e.EmailId)
.Take(10)
.Include(e => e.EmailRecord)
.ToListAsync();
var test2 = await _unitOfWork.Context.PersonEmail
.OrderBy(e => e.EmailId)
.Take(10)
.ToListAsync();
我希望两个查询都返回10个结果,但是test
查询中的6个项目的null
属性具有EmailRecord
(因为EmailRecord表不包含这些特定项目的条目)。但是实际发生的是,test
查询仅返回4个结果,而test2
查询返回预期的10个结果。
实体声明如下:
[Table("PersonEmail")]
public class PersonEmail
{
public Guid PersonId { get; set; }
public Guid EmailId { get; set; }
[ForeignKey("PersonId, EmailId")]
public EmailRecord EmailRecord { get; set; }
}
[Table("EmailRecord")]
public class EmailRecord
{
public Guid PersonId { get; set; }
public Guid EmailId { get; set; }
public DateTimeOffset LastUpdated { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<PersonEmail>().HasKey(x => new { x.PersonId, x.EmailId });
modelBuilder.Entity<EmailRecord>().HasKey(x => new { x.PersonId, x.EmailId });
}
答案 0 :(得分:1)
这是由于(不合适的)关系配置。
定义方式
[ForeignKey("PersonId, EmailId")]
PersonEmail
中的是一对一关系,其中PersonEmail
是依赖(由于FK),而EmailRecord
是校长。
如果是这样,则由于强制FK约束,“由于EmailRecord表不包含那些特定项目的条目”根本不可能发生。因此,EF Core 3.0+ Include
可以正确生成inner join
,它不应该过滤主集合,但是实际上由于数据库中的实际数据关系而可以过滤主集合。
要解决此问题,您必须反映实际的关系,这似乎是另一回事-与主体PersonEmail
和从属EmailRecord
一对一。
删除上面的[ForeignKey]
属性并添加以下流利的配置:
modelBuilder.Entity<PersonEmail>()
.HasOne(x => x.EmailRecord)
.WithOne()
.HasForeignKey<EmailRecord>(x => new { x.PersonId, x.EmailId });
现在Include
将使用left outer join
,并且不会过滤PersonEmail
记录。
有关更多信息,请参阅Relationships - One-to-one EF Core文档。