我正在使用最新版本的 Entity Framework (6.1.3),并且我有以下允许更改客户名称的类:
public class CustomerService
{
public void ChangeName()
{
using (TestModel ctx = new TestModel())
{
var customer = GetCustomer(ctx);
//set new name
customer.Name = "New Name";
SaveCustomer(ctx, customer);
}
}
private Customer GetCustomer(TestModel ctx)
{
//get customer by email
var customer = ctx.Customers
.AsNoTracking()
.Include(n => n.Country) //Load Shipping Country
.Include(n => n.Country1) //Load Billing Country
.Where(n => n.Email == "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="631706101723170610174d000c0e" rel="noreferrer noopener nofollow">[email protected]</a>")
.Single();
return customer;
}
private void SaveCustomer(TestModel ctx, Customer customer)
{
//save back
ctx.Customers.Attach(customer); // getting error here
ctx.Entry(customer).State = EntityState.Modified;
ctx.SaveChanges();
}
}
在 sql server 数据库中我有 2 个表:
客户
-Id
、名称
、ShippingCountryId
(外键)、BillingCountryId
(外键)国家/地区
-ID
、名称
当我调用 ChangeName
方法时,出现以下错误:
Attaching an entity of type 'TestConsoleApp.customermodel.Country' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.
我一直在进行一些调试并发现以下内容:
- 如果我删除
AsNoTracking
调用,则不会出现错误 - 如果我删除其中一个 Include(保留
AsNoTracking
),则不会出现错误
因此,看起来 AsNoTracking
和 2 个相同类型的 Include 的组合导致了该问题。
任何人都可以建议我为什么会收到此错误以及如何解决它吗? (同时保留 AsNoTracking
和 2 Includes 在我的代码中)。
我在其他地方重用了 GetCustomer
方法,这就是为什么我想保留 AsNoTracking
和 2 个包含项。
最佳答案
它与引用导航属性和 AsNotracking
有关。
线路...
ctx.Entry(customer).State = EntityState.Modified;
...将客户
标记为已修改
,但还将两个国家/地区作为未更改
附加到上下文。在这种情况下,两个国家都是相同的。除此之外,他们不是...
通常,当 EF 使用 Include
实例化对象时,EF 只会为对象图中的每个实体创建一个实例。上下文缓存是一个身份映射:每个实体仅出现一次。因此,当两个国家/地区相同时,将在缓存中找到一个 Country
实体。
但是,使用 AsNoTracking
时,EF 不会将任何内容归档到其缓存中。现在创建了同一个国家/地区的两个实例。因此,当它们附加时会出现异常。
关于c# - 多个相同类型的 Include 语句出现奇怪的 Entity Framework 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35668484/