实体框架核心 - 孤立记录

本文关键字:记录 框架 核心 实体 | 更新日期: 2023-09-27 18:34:09

我在一个应用程序中使用实体框架核心(7.0.0-rc1-final(,该应用程序包含一些我无法控制的表(它们来自带有孤立记录的数据馈送(。以下是我创建的一些简单模型来显示此问题:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int BuildingId { get; set; }
    public virtual Building Building { get; set; }
}
public class Building
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Person> People { get; set; }
}

当我尝试查询一个人所在的建筑物的名称并且该记录具有 BuildingId 且在与建筑物相关的表中没有记录时,它会抛出错误。

以下是我计划如何检查孤立记录的示例:

var person = _dbContext.Person
    .AsNoTracking()
    .Where(p => p.Id == personId)
    .Select(p => new
    {
        Name = p.Name,
        HasBuildingName = p.Building == null,
    })
.FirstOrDefault();

这是我在运行上述语句时得到的异常:

二元运算符 Equal 未为类型"System.Int32"定义 和"系统对象"。

理想情况下,我想运行以下代码,如果未找到建筑物 ID,则让"建筑物名称"为空:

   var person = _dbContext.Person
        .AsNoTracking()
        .Where(p => p.Id == personId)
        .Select(p => new
        {
            Name = p.Name,
            BuildingName = p.Building == null ? null : p.Building.Name
        })
        .FirstOrDefault();

这是一个 EF 错误还是有其他方法可以做到这一点?

编辑:

为了清楚起见,这工作得很好,直到我遇到孤立记录的问题:

var person = _dbContext.Person
            .AsNoTracking()
            .Where(p => p.Id == personId)
            .Select(p => new
            {
                Name = p.Name,
                BuildingName = p.Building.Name
            })
            .FirstOrDefault();

实体框架核心 - 孤立记录

EF

无法处理将非空 Id 指向无处作为导航属性的情况。导航属性由 FK 支持,可选关系由 null ID 表示。

如果您的数据库中没有 fk 约束,我会将两个实体实现为不相关,并使用 Join 运算符而不是导航属性查询它们。

var person = _dbContext.Person
            .AsNoTracking()
            .Where(p => p.Id == personId)
            .GroupJoin(_dbContext.Building, x=>x.BuildingId, x=>X.Id,(p,bs)=> new
            {
                Name = p.Name,
                BuildingName = bs.Select(b=>b.Name).FirstOrDefault()
            })
            .FirstOrDefault();