开发者

EF 4.0 UpdateException

I'm using EF 4.0 within VS 2010 RC. I have pretty simple POCO class structure with few dependencies. Each POCO class has a base generic class (EntityObject or ValueObect) with property ID. I have several CRUD tests and only one of them works. This one is very simple where object does not have any dependencies. But when I test something with FK dependencies I always get the same error: System.Data.UpdateException: A value shared across entities or associations is generated in more than one location. Check that mapping does not split an EntityKey to multiple store-generated columns. I've googled that but the only reason of this exception that I found is usage of several contextes which is not my case.

 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;  
       开发者_JAVA技巧     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();                 

So what can be the reason of this exception?


K. I think I found the cause of this kind of issue. I have a situation with a many to many in my EF diagram (Scholarhip table, Survey table, ScholarshipSurvey table {this is a bridge table}). Well after some serious soul searching I found this in my ScholarshipSurvey table entry in the EDMX:

    <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>

I was thinking, no way! Why did the EF make these "identities". They are not in the data model from whence the came. So, when I openned the EDMX using a XML editor (instead of the default double click), I removed the entry StoreGeneratedPattern="Identity" for both the scholarship id and survey id. Then, I tried my normal code for adding items into the collection and removing items from the collection and it WORKED!

All I can think is that this is a bug in EF4 that shouldn't have been. The only other way to solve this is to make the bridge table an object by adding an identity of its own to the table. Gee. Hope this helps some poor soul out there.

Update (rwwilden): There is a Microsoft Connect report for this issue.


However the initial problem has gone after recreation of edmx, yet another one arised. I have class which definition looks like this:

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

And here is MetaValue class definition:

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

Values property in ValueList represents Many-To-many relationship between ValueLists and MetaValues tables (joining table ValueListMetaValues with two FK columns and PK on both). The CRUD test for this item looks like this:

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

So after context.SaveChanges() listName is saved and valOne and valTwo are not. Moreover, after detaching and retreiving this object from DB its Values propety is filled with one value - listName and the Name also (the same object in Name and Values propeties). So is the problem again in edmx, or such structure (with FK and manyTomany in the same entity) is somehow misinterpreted by EF?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜