实体框架核心 - 孤立记录

时间:2016-02-10 23:05:50

标签: c# ef-code-first entity-framework-core

我在一个应用程序中使用Entity Framework Core(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,而BuildingI表中没有任何与其相关的记录会引发错误。

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

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

以下是运行上述语句时遇到的异常:

  

没有为类型'System.Int32'定义二元运算符Equal   和'System.Object'。

理想情况下,我想运行以下代码,如果找不到构建ID,则“BuildingName”为null:

   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();

1 个答案:

答案 0 :(得分:1)

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();