实体框架核心 - 孤立记录
本文关键字:记录 框架 核心 实体 | 更新日期: 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();