1
votes

I'm getting the error when attempting to add to a client-side EntitySet. The following code intermittently fails on the Add method.

// On the DB side this has a primary key field of IDENTITY(1,1) called Id
var map = new EpisodeDictionaryMap();
map.DictionaryName = dictionary; // String
map.Section = section; // String
map.DictionaryVersion = version; // Int32

episode.EpisodeDictionaryMap.Add(map);

I'm also calling Clear() on the EntitySets for Episode and EpisodeDictionaryMap (amongst others) not before every call to this code, but every now and again, when the user changes to a different screen within the app. This is a recent change, so could be part of the problem.

Upon investigating the DomainContext's EpisodeDictionaryMap collection it would appear that sometimes there are in fact multiple 'New' EpisodeDictionaryMap instances, each with an Id of 0, as I would expect prior to saving, and in these instances the save completes without issue, and the correct Ids are assigned to the client-side entities.

Given that it doesn't seem to be an issue to have multiple entries with an Id of 0 in the EntitySet at any one time (at least whilst they're in a "New" state), I don't understand what the error message is trying to tell me.

I've noticed on some related SO questions that Composition can be an issue, however I'm not using it. With the exception of the Episode reference itself there are also no other foreign key references, which also appears to sometimes cause this error.

Suggestions, thoughts? Many thanks!

Edit:

Full exception (no inner exception exists)

System.InvalidOperationException occurred
    Message=An entity with the same identity already exists in this EntitySet.
StackTrace:
    at System.ServiceModel.DomainServices.Client.EntitySet.AddInternal(Entity entity)
    at System.ServiceModel.DomainServices.Client.EntitySet.<Add>b__5(EntitySet l, Entity e)
    at System.ServiceModel.DomainServices.Client.EntitySet.AddAttachInferrer.Visit(Entity entity)
    at System.ServiceModel.DomainServices.Client.EntitySet.AddAttachInferrer.VisitEntityCollection(IEntityCollection entityCollection, PropertyInfo propertyInfo)
    at System.ServiceModel.DomainServices.Client.EntityVisitor.Visit(Entity entity)
    at System.ServiceModel.DomainServices.Client.EntitySet.AddAttachInferrer.Visit(Entity entity)
    at System.ServiceModel.DomainServices.Client.EntitySet.AddAttachInferrer.VisitEntityRef(IEntityRef entityRef, Entity parent, PropertyInfo propertyInfo)
    at System.ServiceModel.DomainServices.Client.EntityVisitor.Visit(Entity entity)
    at System.ServiceModel.DomainServices.Client.EntitySet.AddAttachInferrer.Visit(Entity entity)
    at System.ServiceModel.DomainServices.Client.EntitySet.AddAttachInferrer.VisitEntityRef(IEntityRef entityRef, Entity parent, PropertyInfo propertyInfo)
    at System.ServiceModel.DomainServices.Client.EntityVisitor.Visit(Entity entity)
    at System.ServiceModel.DomainServices.Client.EntitySet.AddAttachInferrer.Visit(Entity entity)
    at System.ServiceModel.DomainServices.Client.EntitySet.AddAttachInferrer.Infer(EntityContainer container, Entity entity, Action`2 action)
    at System.ServiceModel.DomainServices.Client.EntitySet.Add(Entity entity)
    at System.ServiceModel.DomainServices.Client.EntityCollection`1.Add(TEntity entity)
    at TangoSoft.Client.EpisodeExtensions.SaveDictionaryVersion(Episode episode, String dictionary, String section, Int32 version)
2
Have you looked at your table contents? Perhaps the auto-generated PK is intermittently conflicting with existing row(s)Rob
The keys aren't actually generated by the client code anyway, they're generated on DB insert, so that wouldn't really make sense. Even so, setting the Id on the client to distinct but unused values (-1234) still causes the error, so I don't think it's the Id value itself that it's complaining about. That's part of the confusion I'm having in understanding the error.Wayne Cornish
You're right, that wouldn't make sense; I didn't realize you weren't saving your changes back to the DB. Although if you were, a conflict could occur on the PK even with a DB generated value. Are you setting the foreign key somewhere else in your code, or is it left unset? Where do you call SaveChanges()? I would continue debugging by inspecting individual properties of the exception (perhaps an InnerException exists) and looking for clues.Rob
Nope, it's not set anywhere else. That small block of code is the only place an EpisodeDictionaryMap is created, and it's never modified after adding it to the episode (which in turn is setting the Episode association/FK). SaveChanges() is called only after a manually triggered click event, and has not been triggered at the point of the error (I've verified that). I've included the full exception in the question; unfortunately it's utterly useless.Wayne Cornish

2 Answers

0
votes

Verify that the primary key (pull up the .edmx file in xml) for the table in question has StoreGeneratedPattern="Identity" in both sections. There is a known error where EF via the designer modifies one section, but doesn't modify the other section. Look for this in both sections:

<EntityType Name="TIMELINE">
          <Key>
            <PropertyRef Name="ID"/>
          </Key>

  <Property Name="ID" Type="decimal" Nullable="false" Precision="19" StoreGeneratedPattern="Identity" />

See EF4: Bug in StoreGeneratedPattern SSDL

0
votes

After a lot of trial and error I discovered that an entity only indirectly connected to the erroring entity was still hanging around on the context, and keeping an entity with id 0 around. I had been clearing each EntitySet that contained non-lookup data - it turns out that this is not sufficient. Investigating within VS wasn't providing me an easy way to actually find the entity in question, however a profiling with ANTS revealed a few too many things laying around connected solely to my 'lookup' EntitySet entities.

My 'fix' for this is to now clear all of my EntitySets as below:

foreach (var set in _context.EntityContainer.EntitySets)
{
    set.Clear();
}

What still baffles me is that this was an intermittent error; sometimes it didn't matter that multiple entities of type T with Id 0 were on the context, and other times it would error.