Entity Framework 核心 - 孤立记录
Entity Framework Core - orphaned record
我在一个应用程序中使用 Entity Framework Core (7.0.0-rc1-final),它有一些我无法控制的 tables(它们来自数据馈送孤立的记录)。以下是我创建的一些简单模型来说明这个问题:
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,但在与之相关的建筑物 table 中没有任何记录会引发错误。
这是我计划如何检查孤立记录的示例:
var person = _dbContext.Person
.AsNoTracking()
.Where(p => p.Id == personId)
.Select(p => new
{
Name = p.Name,
HasBuildingName = p.Building == null,
})
.FirstOrDefault();
这是我在 运行 执行上述语句时得到的异常:
The binary operator Equal is not defined for the types 'System.Int32'
and 'System.Object'.
理想情况下,我希望 运行 以下代码,如果未找到建筑物 ID,则 "BuildingName" 为空:
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 无法处理将非 null 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();
我在一个应用程序中使用 Entity Framework Core (7.0.0-rc1-final),它有一些我无法控制的 tables(它们来自数据馈送孤立的记录)。以下是我创建的一些简单模型来说明这个问题:
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,但在与之相关的建筑物 table 中没有任何记录会引发错误。
这是我计划如何检查孤立记录的示例:
var person = _dbContext.Person
.AsNoTracking()
.Where(p => p.Id == personId)
.Select(p => new
{
Name = p.Name,
HasBuildingName = p.Building == null,
})
.FirstOrDefault();
这是我在 运行 执行上述语句时得到的异常:
The binary operator Equal is not defined for the types 'System.Int32' and 'System.Object'.
理想情况下,我希望 运行 以下代码,如果未找到建筑物 ID,则 "BuildingName" 为空:
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 无法处理将非 null 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();