【发布时间】:2018-12-13 04:48:55
【问题描述】:
我正在使用 Entity Framework Core 将对象图存储在数据库中。在构建图形的不同时间,我创建一个实体,将其存储到数据库中,然后释放上下文。但是,我遇到了一个问题,即 EFC 试图插入一个在连接到新实体时已经插入的实体。这最好用代码来解释。这是一段简短的重现代码(这是直线代码,但上下文的两种使用发生在代码中的不同时间和位置)。
在第二次调用context.SaveChanges() 时,我得到以下异常:
SqlException:
当 IDENTITY_INSERT 设置为 OFF 时,无法为表“命名空间”中的标识列插入显式值。
当我查看正在执行的 SQL 时,它正在尝试再次插入命名空间实体,可能是因为 myType 正在保存到数据库中并且它引用了 dbNamespace 实体。
// see if namespace is in the db and add it if not
string someNamespaceString = "foobar";
CodeDatabase.Models.Namespace dbNamespace;
using (var context = new CodeFactsContext())
{
dbNamespace = context.Namespace.FirstOrDefault(ns => ns.Namespace1 == someNamespaceString);
if (dbNamespace == null)
{
dbNamespace = new Namespace() { Namespace1 = someNamespaceString };
context.Namespace.Add(dbNamespace);
}
context.SaveChanges();
}
// Type entity created somewhere from the code
var myType = new CodeDatabase.Models.Type()
{
FullName = "foobar.mytype",
ShortName = "mytype",
Namespace = dbNamespace // this is already in the DB
};
// check if myType is in the db and add it if not
using (var context = new CodeFactsContext())
{
var dbType = context.Type.FirstOrDefault(t => t.FullName == myType.FullName);
if (dbType == null)
{
dbType = myType;
context.Add(dbType);
}
context.SaveChanges(); // throws exception
}
知道如何让 EF Core 识别(在第二个 context.SaveChanges() 中)myType 应该插入到数据库中,但 myType.Namespace 不应该因为它已经存在?这两个实体都有一个由 DB 自动生成的 int id,并且 Namespace 的 id 在第一次调用 SaveChanges 后设置为数据库值。我认为 EF Core 会识别出 id 不是 0 并且不会尝试保存它。非常欢迎任何帮助/建议。
【问题讨论】:
-
这只是意味着你的命名空间表有一个标识列。像
PRIMARY KEY IDENTITY (1, 1)这样的东西,你的保存正在尝试写入 SQL 服务器不喜欢的列。 -
我明白这就是它的意思。我在问如何让 EFC 理解它不应该再次编写它,因为实体已经添加到数据库中。
-
不。我认为您仍然误解了它的含义。这意味着您永远不应该写入该列(除非您尝试使用身份复制数据),而不是您不应该再次写入。
-
好的。我想我是误会了。我并没有明确地尝试写入该专栏。我正在创建命名空间实体,并且在第一次调用 context.SaveChanges() 时,它成功保存了命名空间实体。然后第二个 SaveChanges()(它正在尝试写入 Type 实体)是发生故障的地方。我不是想写那个专栏,我不确定我在做什么让 EFC 尝试写那个专栏。
标签: c# entity-framework entity-framework-core