首页 > 解决方案 > 无法使用 EF Core 在 ASP.NET Core 中创建相关实体

问题描述

我在 Entity Framework Core 2.0 中创建相关实体时遇到问题。我刚刚创建了解决方案,其中包括一个 Asp.Net Core 后端项目和一个充当客户端的 UWP 项目。两种解决方案共享模型。这两个模型是:

public class UnitOfWork {
    public int UnitOfWorkId { get; set; }
    public string Name { get; set; }
    public Human Human { get; set; }
}

public class Human {
    public int HumanId { get; set; }
    public string Name { get; set; }
    public List<UnitOfWork> WorkDone { get; set; }
}

如您所见,模型非常简单。一human有多units of work。顺便说一句,后端连接到 Azure SQL 数据库。我已经看到了迁移类,并且数据库模式对我来说看起来不错。

我遇到的问题是,当我想创建一个unit of work引用现有的human时,使用 HTTP。控制器相当简单:

[HttpPost]
public UnitOfWork Post([FromBody] UnitOfWork unitOfWork) {
    using (var db = new DatabaseContext()) {
        db.UnitsOfWork.Add(unitOfWork);
        var count = db.SaveChanges();
        Console.WriteLine("{0} records saved to database", count);
    }
    return unitOfWork;
}

再说一次,这里没什么特别的。

如何创建工作单元并将其分配给现有人员?如果我与现有的人一起尝试,以这种方式

var humans = await Api.GetHumans();
var firstHuman = humans.First();

var unitOfWorkToCreate = new UnitOfWork() {
    Name = TbInput.Text,
    Human = firstHuman,
};

我收到此错误:

当 IDENTITY_INSERT 设置为 OFF 时,无法在表“Humans”中插入标识列的显式值

我觉得将 IDENTITY_INSERT 设置为 ON 可以解决我的问题,但这不是我想要做的。在客户端中,我将选择一个现有的human,记下 的名称unit of work,然后创建后者。这是正确的方法吗?

编辑:在@Ivan Stoev 回答之后,我将UnitOfWork控制器更新为 attach unitofwork.Human。这导致

Newtonsoft.Json.JsonSerializationException: '反序列化数组时意外结束。路径“human.workDone”,第 1 行,位置 86。

调查 - 在这里看到- EFCore 期望human.WorkDone在构造函数中创建集合(如 ),所以我做到了,不再反序列化空值。但是,现在我有一个自引用循环:

Newtonsoft.Json.JsonSerializationException:检测到“PlainWorkTracker.Models.UnitOfWork”类型的自引用循环。路径“human.workDone”。

有任何想法吗?谢谢!

标签: entity-frameworkazureasp.net-coreentity-framework-coreef-core-2.0

解决方案


有问题的操作属于保存断开连接的实体类别。

Add方法将图中当前未跟踪的所有实体标记为新的 ( Added),然后SaveChanges尝试将它们插入数据库。

您需要一种方法来告诉 EF 这unitOfWork.Human是一个现有实体。实现这一点的最简单方法是在调用之前Attach将其(将其标记为Unchanged,即存在)到上下文中Add

db.Attach(unitOfWork.Human);
db.Add(unitOfWork);
// ...

推荐阅读