gpt4 book ai didi

c# - Entity Framework 在两个不同的上下文中两次插入实体

转载 作者:行者123 更新时间:2023-11-30 21:31:05 24 4
gpt4 key购买 nike

我正在使用 Entity Framework Core 将对象图存储在数据库中。在构建图形的不同时间,我创建了一个实体,将其存储到数据库中,然后发布了上下文。但是,我遇到了一个问题,即 EFC 试图插入一个在连接到新实体时已经插入的实体。这最好用代码来解释。这是一段简短的重现代码(这是直线代码,但是上下文的两种使用发生在代码中的不同时间和位置)。

在第二次调用 context.SaveChanges() 时,出现以下异常:

异常:

Cannot insert explicit value for identity column in table 'Namespace' when IDENTITY_INSERT is set to 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 不应该因为它已经存在了吗?这两个实体都有一个由数据库自动生成的 int id,在第一次调用 SaveChanges 后,Namespace 的 id 被设置为数据库值。我以为 EF Core 会识别出 id 不是 0 并且不会尝试保存它。非常欢迎任何帮助/建议。

最佳答案

I thought EFC would recognize that the id is not 0 and not try to save it.

问题是您正在使用 Add 方法,该方法将所有可访问和未跟踪的实体标记为新实体,而不管键值如何(这是为了允许身份插入方案)。这在 Disconnected Entities - Working with graphs - All new/all existing entities 中有解释。 .虽然您的场景属于 Mix of new and existing entities .

Any idea how to get EFC to recognize (in the second context.SaveChanges) that myType should be inserted into the database, but myType.Namespace should not because it's already there? Both of the entities have an int id that is autogenerated by the DB and the id of Namespace is set to the database value after the first call to SaveChanges.

实际上在第二个文档链接中解释了一个简单的解决方案:

With auto-generated keys, Update can again be used for both inserts and updates, even if the graph contains a mix of entities that require inserting and those that require updating

“再次”指的是 Saving single entities :

The Update method normally marks the entity for update, not insert. However, if the entity has a auto-generated key, and no key value has been set, then the entity is instead automatically marked for insert.

幸运的是,您的实体使用自动生成的键,因此只需使用 Update 而不是 Add:

if (dbType == null)
{
dbType = myType;
context.Update(dbType); // <--
}

关于c# - Entity Framework 在两个不同的上下文中两次插入实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53749244/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com