【问题标题】:EF4 - POCO - SaveChanges unexpectadly duplicates items in the lookup tableEF4 - POCO - 保存更改意外重复查找表中的项目
【发布时间】:2011-05-02 03:21:19
【问题描述】:

我正在使用带有 POCO 的 EF4,下面的代码是我必须更新许可证的代码。我只在此处粘贴了与问题相关的代码部分,即添加 LicenseDetails。

问题在于,对于插入的每个 LicenseDetail,EF 还会意外地将行添加到“Item”查找表中。为什么?!

在数据库(SQLServer 2008)中定义的两个表的关系如下图,我先做Database,所以EF根据这个生成实体的关系。

ALTER TABLE [dbo].[LicenseDetail]  
WITH CHECK ADD  CONSTRAINT [FK_LicenseDetail_Item] FOREIGN KEY([ItemId])
REFERENCES [dbo].[Item] ([Id])
GO

ALTER TABLE [dbo].[LicenseDetail] CHECK CONSTRAINT [FK_LicenseDetail_Item]
GO  

更新方法:

    public static void UpdateLicense(License license)
    {
        using (ALISEntities context = new ALISEntities())
        {
            context.ContextOptions.ProxyCreationEnabled = true;

            var storedLicense = 
                context.Licenses.Include("LicenseDetails")
                .Where(o => o.Id == license.Id).SingleOrDefault();

            //////////////////////////////////////////////////////////////
            // license details to add
            List<LicenseDetail> toAdd = new List<LicenseDetail>();

            foreach (LicenseDetail ld in license.LicenseDetails)
            {
                if (storedLicense.LicenseDetails
                    .Where(d => d.ItemId == ld.ItemId).Count() == 0)
                {
                    toAdd.Add(ld);
                }
            }

            toAdd.ForEach(i => storedLicense.LicenseDetails.Add(i));

            context.SaveChanges();
        }
    }

【问题讨论】:

    标签: entity-framework-4 poco


    【解决方案1】:

    当您将新的 LicenseDetails 添加到上下文时,您还会添加这些 LicenseDetails 引用的项目。因为 context 不知道 Items 已经存在于数据库中,所以它会添加它们。您需要通过调用 context.Items.Attach(licenseDetail.Item) 告诉上下文项目已经在数据库中。

    您也可以尝试使用

    context.Licenses.Include("LicenseDetails").Find(license.Id);
    

    而不是

    context.Licenses.Include("LicenseDetails")
                    .Where(o => o.Id == license.Id).SingleOrDefault();
    

    根本不需要使用 toAdd 列表 - 只需在第一个 foreach 循环中继续添加 licenseDetails 即可。

    【讨论】:

    • Jakub,非常感谢您的帮助。现在我明白了!也感谢您提供的额外提示!
    • @user428774 - 不客气!我必须承认,这有点不直观,尤其是当您从不太“面向实体”的世界中走出来时
    • Jakub,昨天我在家里回复你的回复并将你的答案标记为已接受的答案,因为我相信你。但是,现在在办公室并测试您的解决方案,我仍然遇到同样的问题。
    【解决方案2】:

    我最终不得不为每个添加的 LicenseDetail 发出 context.ObjectStateManager.ChangeObjectState(d.Item, EntityState.Unchanged)。这样就解决了问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-22
      • 2021-12-19
      • 2011-01-03
      • 2018-05-11
      相关资源
      最近更新 更多