views:

509

answers:

3

Hi 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;  
            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?

A: 

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?

Voice
The problem still exists. My repository classes btw are simple wrappes around IObjectSet<> interfaces and factories call context's CreateObject. I simplified valueList class definition (changed Name property type to string). Saving of saveral Metavalue items simultaneously doesn't really work for this type - context.SaveChanges saves only the fisrt item but not the second one. If I add one MetaValue to the Values property, call SaveChanges on context, after that add second value and call SaveChanges again both items will be saved.
Voice
+3  A: 

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.

Nate T.
Thanks, this definitely helped.
Ronald Wildenberg
Yes, nasty bug, and your workaround works until MSFT fixes the problem.
Hightechrider
Thank you. This fixed the problem for me.
bgs264
A: 

Hello:

I am having the same issue.

I had an EF Model with 4 levels hierarchy working on VS 2010 Beta 1 and Beta2 working perfectly. Now, with RC, this exception is thrown:

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.

The problem also appears in a simple hierarchy model like person<-customer. I have done som projects with hierarchy and I never had any problem.

I a sample project I have made (Person <- Customer, with no Autogenerated keys) the SaveChanges completes. But, if I enable the (only) autogenerated key in Person, the exception is thrown...

Hoping is a bug of .NET Framework 4 RC

Sergio