|
This isn't really a DevForce issue, more of an Entity Framework one, and a rather confusing one to us. We started using DevForce/EF over a year and a half ago, and at that time it seemed that the proper/only way of assigning a foreign-key relationship was to set the child's foreign key to the parent's ID, instead of assigning the child's parent entity property to the new parent entity. It could be that we prematurely jumped to this conclusion, but it was the only way we could get things to work at the time.
That said, we just spent over a day trying to track down an issue that we hadn't seen before. We've a parent/child relationship as described above, where the child table (SourcingDecision) has a foreign-key relationship to the parent (UnitCycle) via SourcingDecision.UnitCycleID <==> UnitCycle.UniqueID. SourcingDecision.UnitCycleID is nullable, so the relationship is a 0/1 to many. The model generated agrees with this relationship, and sets up the entities properly. We had a situation where we had a single UnitCycle, and two SourcingDecisions with both SourcingDecisions pointing to the same UnitCycle (child A to parent A, child B to parent A). We wanted to create a second UnitCycle, and assign one of the SourcingDecisions to the new UnitCycle (child A to parent A, child B to parent B). Normally what we would do in this case would be to set SourcingDecision B's UnitCycleID property to the new UnitCycle.UniqueID (EntityState == Added), however when saving changes, we would receive the exception below. For whatever reason, it seems the Entity Framework believes that we're attempting to add a second UnitCycle to a single SourcingDecision (child B to parent A and B) which is definitely not allowed.
The workaround appears to be just to assign the entities directly. In other words, instead of:
UnitCycle unitCycle = new UnitCycle();
entityManager.AddEntity(unitCycle);
sourcingDecision.UnitCycleID = unitCycle.UniqueID;
entityManager.SaveChanges();
What works is:
UnitCycle unitCycle = new UnitCycle();
entityManager.AddEntity(unitCycle);
sourcingDecision.UnitCycle = unitCycle;
entityManager.SaveChanges();
But... why? Why does assigning the key and saving result in an exception where assigning the entity and saving does not.
A first chance exception of type 'IdeaBlade.EntityModel.EntityManagerSaveException' occurred in IdeaBlade.EntityModel.dll
Multiplicity constraint violated. The role 'UnitCycle' of the relationship 'ProModel_AST_DB.FK_SourcingDecision_UnitCycle' has multiplicity 1 or 0..1.
at IdeaBlade.EntityModel.EntityManager.HandleSaveResultException(SaveWorkState saveWorkState, Boolean isAsyncOp)
at IdeaBlade.EntityModel.EntityManager.SaveChangesCore(IEnumerable entities, SaveOptions saveOptions)
at IdeaBlade.EntityModel.EntityManager.SaveChanges(IEnumerable entities, SaveOptions saveOptions)
at IdeaBlade.EntityModel.EntityManager.SaveChanges()
at AST.Common.Sourcing.LockSmith.Unlock(IEnumerable`1 entityInfos) in C:\_source\AST\Current\Common\Sourcing\LockSmith.cs:line 90
at AST.Web.SourcingService.Source(Guid userID, Guid coaID, ConcurrencyEntityInfo requirementInfo, ConcurrencyEntityInfo unitInfo, SourcingDecisionOptions options) in C:\_source\AST\Current\Web\SourcingService.svc.cs:line 62
Multiplicity constraint violated. The role 'UnitCycle' of the relationship 'ProModel_AST_DB.FK_SourcingDecision_UnitCycle' has multiplicity 1 or 0..1.
at System.Data.Objects.DataClasses.EntityReference`1.AddToLocalCache(IEntityWrapper wrappedEntity, Boolean applyConstraints)
at System.Data.Objects.EntityEntry.TakeSnapshotOfSingleRelationship(RelatedEnd relatedEnd, NavigationProperty n, Object o)
at System.Data.Objects.EntityEntry.TakeSnapshotOfRelationships()
at System.Data.Objects.Internal.EntityWrapperWithoutRelationships`1.TakeSnapshotOfRelationships(EntityEntry entry)
at System.Data.Objects.ObjectContext.AddSingleObject(EntitySet entitySet, IEntityWrapper wrappedEntity, String argumentName)
at System.Data.Objects.DataClasses.RelatedEnd.AddEntityToObjectStateManager(IEntityWrapper wrappedEntity, Boolean doAttach)
at System.Data.Objects.DataClasses.RelatedEnd.AddGraphToObjectStateManager(IEntityWrapper wrappedEntity, Boolean relationshipAlreadyExists, Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Objects.DataClasses.RelatedEnd.IncludeEntity(IEntityWrapper wrappedEntity, Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Objects.DataClasses.EntityCollection`1.Include(Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Objects.DataClasses.RelatedEnd.WalkObjectGraphToIncludeAllRelatedEntities(IEntityWrapper wrappedEntity, Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Objects.DataClasses.RelatedEnd.AddGraphToObjectStateManager(IEntityWrapper wrappedEntity, Boolean relationshipAlreadyExists, Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Objects.DataClasses.RelatedEnd.IncludeEntity(IEntityWrapper wrappedEntity, Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Objects.DataClasses.EntityReference`1.Include(Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Objects.DataClasses.RelatedEnd.WalkObjectGraphToIncludeAllRelatedEntities(IEntityWrapper wrappedEntity, Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Objects.DataClasses.RelatedEnd.AddGraphToObjectStateManager(IEntityWrapper wrappedEntity, Boolean relationshipAlreadyExists, Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Objects.DataClasses.RelatedEnd.IncludeEntity(IEntityWrapper wrappedEntity, Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Objects.DataClasses.EntityCollection`1.Include(Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Objects.DataClasses.RelationshipManager.AddRelatedEntitiesToObjectStateManager(Boolean doAttach)
at System.Data.Objects.ObjectContext.AddObject(String entitySetName, Object entity)
at IdeaBlade.EntityModel.Edm.EdmSaveHelper.AddObjectStateEntry(Entity entity, EntityMetadata metadata)
at IdeaBlade.EntityModel.Edm.EdmSaveHelper.HandleModified(Entity entity, EntityMetadata metadata)
at IdeaBlade.EntityModel.Edm.EdmSaveHelper.ProcessEntity(Entity entity, EntityMetadata metadata)
at IdeaBlade.EntityModel.Edm.EdmSaveHelper.ProcessSaves(IEnumerable`1 groupsByType)
at IdeaBlade.EntityModel.Edm.EdmSaveHelper.SaveWithinContext()
at IdeaBlade.EntityModel.Edm.EdmSaveHelper.Save()
The thread '<No Name>' (0x12b4) has exited with code 0 (0x0).
|