c# - 多个相同类型的 Include 语句出现奇怪的 Entity Framework 错误

标签 c# sql-server asp.net-mvc entity-framework

我正在使用最新版本的 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/

相关文章:

c# - Zed-Graph 以编程方式将比例设置为默认值

c# - 使用 Umbraco.Core.Persistence 从带有枚举的模型创建数据库表

C#,多维数组的多线程填充

.net - 从数据适配器填充数据表时出现错误

sql-server - 获取在 RowGuid 中插入的值?

asp.net-mvc - Kendo UI Treeview 绑定(bind)

asp.net-mvc - 将 ASP.NET MVC 应用程序部署到 IIS7 并保持干净的 web.config

c# - 排序子序列的最有效排序算法

sql-server - ADsDSOObject和.NET为objectSID返回不同的值(类型)

c# - xUnit.net 与 Ninject