I didn't find yet a good solution to this problem (similar ticket here EF5 update disconnected graph (n-tier) one-to-many).
I found and followed this example: http://entityframeworktutorial.net/update-many-to-many-entities-in-entity-framework.aspx#.UTBeTDBhif8.
This works just fine, but it creates a duplicate of the related entities (with sql profiler I saw the Insert into RelatedEntities .. I would expected just an insert / update on the MyEntities_Related join table and I don't understand why EF makes an insert on the RelatedEntities table :(
And here is my code:
public void AddOrUpdate(MyEntity entity) {
var dbEntity = _context.MyEntities
.Include(e => e.RelatedEntitis)
.Where(e => e.ID == entity.ID)
.SingleOrDefault();
var newRelated = entity.RelatedEntitis.ToList<RelatedEntity>();
var dbRelated = dbEntity.RelatedEntity.ToList<RelatedEntity>();
_context.Entry(dbEntity).CurrentValues.SetValues(entity);
var comparer = new EqualityComparer();
var addedRelated = newRelated.Except(dbRelated, comparer).ToList<RelatedEntity>();
var deletedRelated = dbRelated.Except(newRelated, comparer).ToList<RelatedEntity>();
addedRelated.ForEach(e => dbEntity.RelatedEntity.Add(e));
deletedRelated.ForEach(e => dbEntity.RelatedEntity.Remove(e));
}
public class EqualityComparer : IEqualityComparer<RelatedEntity>
{
public int GetHashCode(RelatedEntity obj)
{
return (obj == null) ? 0 : obj.ID.GetHashCode();
}
public bool Equals(RelatedEntity x, RelatedEntity y)
{
if (ReferenceEquals(x, y)) return true;
if (x == null || y == null) return false;
return x.ID == y.ID;
}
}
the db schema is like the following:
|------------------|
| Table MyEntities |
|------------------|
| int ID //PK |
|------------------|
|--------------------------|
| Table MyEntities_Related |
|--------------------------|
| int MyEntityID |
| int RelatedID |
|--------------------------|
|-----------------------|
| Table RelatedEntities |
|-----------------------|
| int RelatedID //PK |
| string Name |
|-----------------------|
any help is appreciated :)
SOLUTION I don't know if it's the best, but it works for me and I think it has sense. EF creates a duplicate of the relatedentities because they were detached, I changed my code in this way:
public void AddOrUpdate(MyEntity entity) {
var dbEntity = _context.MyEntities
.Include(e => e.RelatedEntitis)
.Where(e => e.ID == entity.ID)
.SingleOrDefault();
//replace entities with those taken from the context
var relatedEntities = _context.RelatedEntities;
var detachedEntities = entity.RelatedEntities;
entity.RelatedEntities = new List<RelatedEntity>();
foreach (var ent in detachedEntities)
{
entity.RelatedEntities.Add(relatedEntities .Where(e => e.ID == hop.ID).SingleOrDefault());
}
var newRelated = entity.RelatedEntitis.ToList<RelatedEntity>();
var dbRelated = dbEntity.RelatedEntity.ToList<RelatedEntity>();
_context.Entry(dbEntity).CurrentValues.SetValues(entity);
_context.Entry(dbEntity.RelatedEntity).CurrentValues.SetValues(entity.RelatedEntitis);
var comparer = new EqualityComparer();
var addedRelated = newRelated.Except(dbRelated, comparer).ToList<RelatedEntity>();
var deletedRelated = dbRelated.Except(newRelated, comparer).ToList<RelatedEntity>();
addedRelated.ForEach(e => dbEntity.RelatedEntity.Add(e));
deletedRelated.ForEach(e => dbEntity.RelatedEntity.Remove(e));
}
来源:https://stackoverflow.com/questions/15153761/ef5-many-to-many-update-disconnected-scenario