无法使用 EF Core 在 ASP.NET Core 中创建相关实体
Can't create related entity in ASP.NET Core with EF Core
我在 Entity Framework Core 2.0 中创建相关实体时遇到问题。我刚刚创建了解决方案,包括一个 Asp.Net 核心后端项目和一个充当客户端的 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 数据库。我看过迁移 类,数据库模式对我来说看起来不错。
我遇到的问题是当我想使用 HTTP 创建引用现有 human
的 unit of work
时。控制器相当简单:
[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,
};
我收到这个错误:
Cannot insert explicit value for identity column in table 'Humans' when IDENTITY_INSERT is set to OFF
我觉得将IDENTITY_INSERT设置为ON可以解决我的问题,但这不是我想要做的。在客户端中,我将 select 一个现有的 human
,写下 unit of work
的名称,然后创建后者。这是正确的方法吗?
编辑:按照@Ivan Stoev 的回答,我更新了 UnitOfWork
控制器以附加 unitofwork.Human
。这导致
Newtonsoft.Json.JsonSerializationException: 'Unexpected end when deserializing array. Path 'human.workDone', line 1, position 86.'
调查 - 看到 here - EFCore 期望在构造函数中创建集合(如 human.WorkDone
),所以我做到了,不再进行空值反序列化。但是,现在我有一个自引用循环:
Newtonsoft.Json.JsonSerializationException: Self referencing loop detected with type 'PlainWorkTracker.Models.UnitOfWork'. Path 'human.workDone'.
有什么想法吗?谢谢!
相关操作属于 Saving Disconnected Entities 类别。
Add
方法将图中当前未跟踪的所有实体标记为新实体 (Added
),然后 SaveChanges
将尝试将它们插入数据库。
您需要一种方法来告诉 EF unitOfWork.Human
是一个现有实体。实现这一点的最简单方法是在调用 Add
:
之前将其 Attach
(将其标记为 Unchanged
,即存在)到上下文
db.Attach(unitOfWork.Human);
db.Add(unitOfWork);
// ...
我在 Entity Framework Core 2.0 中创建相关实体时遇到问题。我刚刚创建了解决方案,包括一个 Asp.Net 核心后端项目和一个充当客户端的 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 数据库。我看过迁移 类,数据库模式对我来说看起来不错。
我遇到的问题是当我想使用 HTTP 创建引用现有 human
的 unit of work
时。控制器相当简单:
[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,
};
我收到这个错误:
Cannot insert explicit value for identity column in table 'Humans' when IDENTITY_INSERT is set to OFF
我觉得将IDENTITY_INSERT设置为ON可以解决我的问题,但这不是我想要做的。在客户端中,我将 select 一个现有的 human
,写下 unit of work
的名称,然后创建后者。这是正确的方法吗?
编辑:按照@Ivan Stoev 的回答,我更新了 UnitOfWork
控制器以附加 unitofwork.Human
。这导致
Newtonsoft.Json.JsonSerializationException: 'Unexpected end when deserializing array. Path 'human.workDone', line 1, position 86.'
调查 - 看到 here - EFCore 期望在构造函数中创建集合(如 human.WorkDone
),所以我做到了,不再进行空值反序列化。但是,现在我有一个自引用循环:
Newtonsoft.Json.JsonSerializationException: Self referencing loop detected with type 'PlainWorkTracker.Models.UnitOfWork'. Path 'human.workDone'.
有什么想法吗?谢谢!
相关操作属于 Saving Disconnected Entities 类别。
Add
方法将图中当前未跟踪的所有实体标记为新实体 (Added
),然后 SaveChanges
将尝试将它们插入数据库。
您需要一种方法来告诉 EF unitOfWork.Human
是一个现有实体。实现这一点的最简单方法是在调用 Add
:
Attach
(将其标记为 Unchanged
,即存在)到上下文
db.Attach(unitOfWork.Human);
db.Add(unitOfWork);
// ...