2013-03-01 55 views
3

我还没有找到一个很好的解决方案来解决这个问题(类似这里的门票EF5 update disconnected graph (n-tier) one-to-many)。EF5多对多更新断开连接的场景

我发现并遵循此示例:http://entityframeworktutorial.net/update-many-to-many-entities-in-entity-framework.aspx#.UTBeTDBhif8

这工作得很好,但它创建了相关实体的副本(使用sql profiler,我看到了Insert into RelatedEntities ..我只希望在MyEntities_Related连接表上插入/更新,但我不明白为什么EF使得在RelatedEntities表:(

这里插入是我的代码:

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

DB模式是这样的:

|------------------| 
| Table MyEntities | 
|------------------| 
| int ID //PK  | 
|------------------| 


|--------------------------| 
| Table MyEntities_Related | 
|--------------------------| 
| int MyEntityID   | 
| int RelatedID   | 
|--------------------------| 


|-----------------------| 
| Table RelatedEntities | 
|-----------------------| 
| int RelatedID //PK | 
| string Name   | 
|-----------------------| 

任何帮助表示赞赏:)

+0

可能是我unserstand ..我试图更新实体分离以及相关的为好,所以EF无法理解我的相关内容已经存在并且插入了两次。如果我加载相关似乎按我的预期工作。我会尽快复制粘贴我的解决方案,确保它的工作正常。 – Davide 2013-03-01 10:20:58

回答

3

SOLUTION 我不知道这是否是最好的,但它为我工作,我认为它的意义。 EF创建relatedentities的副本,因为他们是超然的, 我改变了我的代码是这样的:

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)); 
} 
+0

_context.Entry(dbRelatedEntities).CurrentValues.SetValues(RelatedEntities);不见了。如果它添加了我会赞成它。 – 2013-05-25 23:07:04

+0

你是对的,我忘记了路线。代码现在已更新。 – Davide 2013-06-06 07:58:28

+0

以下是关于如何编写通用版本的代码http://goo.gl/2sCky – 2013-07-11 23:01:19