EF 4.0 UpdateException

时间:2010-02-15 15:36:20

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

我在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();                 

那么这个例外的原因是什么?

2 个答案:

答案 0 :(得分:3)

ķ。我想我找到了这类问题的原因。我的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

答案 1 :(得分:0)

然而,在重新制作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分离和检索此对象后,其值的值由一个值填充 - listName和Name(名称和值属性中的相同对象)。那么edmx中的问题又是如此,或者这样的结构(在同一个实体中有FK和manyTomany)被EF错误解释?