【问题标题】:EF 4.0 UpdateExceptionEF 4.0 更新异常
【发布时间】:2010-02-15 15:36:19
【问题描述】:

我在 VS 2010 RC 中使用 EF 4.0。 我有非常简单的 POCO 类结构,几乎没有依赖关系。每个 POCO 类都有一个带有属性 ID 的基本泛型类(EntityObject 或 ValueObect)。我有几个 CRUD 测试,只有一个有效。这个非常简单,对象没有任何依赖关系。但是,当我使用 FK 依赖项测试某些东西时,我总是会遇到相同的错误:System.Data.UpdateException:在多个位置生成跨实体或关联共享的值。检查映射是否不会将 EntityKey 拆分为多个存储生成的列。 我已经用谷歌搜索了,但我发现这个异常的唯一原因是使用了几个上下文,这不是我的情况。

 using (IEntityModelContext context = new EFDataContext()) {  
            var licTypeFact = context.GetFactory<LicenceType>();  
            var metaValFact = context.GetFactory<MetaValue>();  
            var cultSpecFact = context.GetFactory<CultureSpecificValue>();  
            LicenceType licType = licTypeFact.CreateObject();  
            Assert.IsNotNull(licType);  
            Assert.IsTrue(licType.IsTransient);  
            licType.AdvancedFeatureSet = true;  
            licType.BasicFeatureSet = true;  
            licType.MaxUsers = 10;  
            licType.MonthDuration = 1;  
            MetaValue licTypeName = metaValFact.CreateObject();  
            licTypeName.Name = "TestLicType";  
            CultureSpecificValue licNameEng = cultSpecFact.CreateObject();  
            licNameEng.Value = "Test Licence";  
            licNameEng.Culture = context.CultureRepository.Load(cult => cult.Name == "Eng");  
            licNameEng.MetaValue = licTypeName;  
            licTypeName.CultureSpecificValues = new List<CultureSpecificValue>();  
            licTypeName.CultureSpecificValues.Add(licNameEng);  
            licType.Name = licTypeName;  
            licType.NumberOfQuestionsPerSurvey = 1;  
            licType.NumberOfResponsesPerSurvey = 2;  
            licType.NumberOfSurveys = 3;  
            licType.PerUserPrice = 10;  
            licType.Price = 100;  
            context.LicenceTypeRepository.Add(licType);  
            int res = context.SaveChanges();                 

那么这个异常的原因是什么?

【问题讨论】:

  • 这里没有显示很多自定义代码,我强烈怀疑错误存在。我建议删除间接层并仅使用上下文。错误会消失。然后将间接添加回来,直到错误再次出现。
  • 感谢克雷格。我重新生成了 edmx,这个问题就消失了。

标签: .net entity-framework visual-studio-2010


【解决方案1】:

K。我想我找到了这种问题的原因。我的 EF 图中存在多对多的情况(Scholarhip 表、Survey 表、ScholarshipSurvey 表{这是一个桥表})。好吧,经过一番认真的反省后,我在 EDMX 的 ScholarshipSurvey 表条目中找到了这个:

    <EntityType Name="ScholarshipSurvey">
      <Key>
        <PropertyRef Name="ScholarshipID" />
        <PropertyRef Name="SurveyID" />
      </Key>
      <Property Name="ScholarshipID" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
      <Property Name="SurveyID" Type="int" Nullable="false" StoreGeneratedPattern="Identity"/>
    </EntityType>

我在想,不可能! EF为什么要制作这些“身份”。它们不在数据模型中。因此,当我使用 XML 编辑器(而不是默认的双击)打开 EDMX 时,我删除了奖学金 ID 和调查 ID 的条目 StoreGeneratedPattern="Identity"。然后,我尝试了将项目添加到集合中并从集合中删除项目的正常代码,它工作正常!

我能想到的是,这是 EF4 中不应该出现的错误。解决此问题的唯一其他方法是通过将其自己的标识添加到表中来使桥表成为对象。哎呀。希望这可以帮助一些可怜的人。

更新(rwwilden):此问题有一个Microsoft Connect report

【讨论】:

  • 谢谢,这绝对有帮助。
  • 是的,讨厌的错误,在 MSFT 解决问题之前,您的解决方法有效。
  • 谢谢。这解决了我的问题。
【解决方案2】:

然而,在重新创建 edmx 之后,最初的问题已经消失,但又出现了另一个问题。我有一个定义如下的类:

  public class ValueList: EntityObject<Int32> {        
        public virtual MetaValue Name { get; set; }       
        public virtual IList<MetaValue> Values { get; set; }      
     }

这是 MetaValue 类定义:

  public class MetaValue :
 EntityObject<Int32> {        
        public string Name { get; set; }       
         public virtual IList<CultureSpecificValue>
 CultureSpecificValues { get; set; }   
    }

ValueList 中的Values 属性表示ValueLists 和MetaValues 表之间的多对多关系(连接表ValueListMetaValues 与两个FK 列和两个PK)。 此项目的 CRUD 测试如下所示:

 using (IEntityModelContext context =
 new EFDataContext()) {  
                var valueListFact = context.GetFactory<ValueList>();  
                 ValueList newValList = valueListFact.CreateObject();  
                 Assert.IsNotNull(newValList);  
                Assert.IsTrue(newValList.IsTransient);  
                 var metaValFact = context.GetFactory<MetaValue>();  
                 var cultSpecFact = context.GetFactory<CultureSpecificValue>();  
                 MetaValue listName = metaValFact.CreateObject();  
                 MetaValue valOne = metaValFact.CreateObject();  
                 MetaValue valTwo = metaValFact.CreateObject();  
                 listName.Name = "list";  
                 valOne.Name = "One";  
                 valTwo.Name = "Two";                  
                 newValList.Name = listName;  
                 newValList.Values = new List<MetaValue>() { valOne, valTwo
 };  
                 context.ValueListRepository.Add(newValList);  
                 context.SaveChanges();

所以在 context.SaveChanges() listName 被保存之后 valOne 和 valTwo 没有。此外,在从 DB 中分离和检索此对象后,它的 Values 属性填充了一个值 - listName 和 Name (名称和 Values 属性中的相同对象)。那么问题又是在 edmx 中,还是这种结构(FK 和 manyTomany 在同一个实体中)在某种程度上被 EF 误解了?

【讨论】:

  • 问题依然存在。顺便说一句,我的存储库类是 IObjectSet 接口和工厂调用上下文的 CreateObject 的简单包装。我简化了 valueList 类定义(将 Name 属性类型更改为字符串)。同时保存保存的元值项目对于这种类型实际上不起作用 - context.SaveChanges 只保存第一个项目,而不是第二个项目。如果我向 Values 属性添加一个 MetaValue,请在上下文中调用 SaveChanges,然后添加第二个值并再次调用 SaveChanges,这两个项目都将被保存。
猜你喜欢
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多