实体框架5不会插入自引用多对多关系

时间:2013-01-02 17:17:53

标签: c# entity-framework entity-framework-5 self-reference

我无法弄清楚为什么这个配置不会为db生成一个insert语句。我正在通过SQL Profiler进行检查。

这是我通过Visio的模型:

visiomodel

这是我的edmx(这是数据库优先)。圆圈显示自我引用关系回到GeoBoundary。

edmxmodel

这是我的代码:

public void UpdateAssocs(Dictionary<int, List<int>> fromTo) {
  //iterate through each dictionary entry
  foreach (KeyValuePair<int, List<int>> entry in fromTo) {
    using (TransactionScope scope = new TransactionScope()) {
      //get a reference to the parent geoboundary for this entry
      GeoBoundary parent = contactContext.GeoBoundaries
        .FirstOrDefault(x => x.GeoID == entry.Key);
      //test to see if the parent is null, it shouldn't be b/c this dictionary was generated 
      // from a list of database values (but shit happens so throw an error if it is null)
      if (parent != null) {
        foreach (int childID in entry.Value) {
          //check to see if the child exists in the parents list of children
          GeoBoundary child = parent.GeoBoundaryAssocTo
            .FirstOrDefault(x => x.GeoID == childID);
          if (child == null) {
            //get a ref to the GeoBoundary that SHOULD be tied to the parent (it should exist but there just 
            // isn't an established relationship in the db)
            child = contactContext.GeoBoundaries
              .FirstOrDefault(x => x.GeoID == childID);
            //check the damn thing again b/c you never want to assume...
            // but if it's still null then do nothing!
            if (child != null) {
              parent.GeoBoundaryAssocTo.Add(child);                  
              contactContext.SaveChanges();
            }
          }
        }
      }
      else {
        throw new Exception(@"Parent GeoID passed to UpdateAssocs method or GeoID is null.");
      }
      scope.Complete();
    }
  }
}

当我在调试器中找到parent.GeoBoundaryAssocTo.Add(child);时,我确保父母和孩子都存在,然后我逐步完成,但我在探查器中什么也得不到。是什么赋予了?这两个实体是否已存在于数据库中并且除了关系之外我没有改变任何问题,这是一个问题吗?如果是,那么我如何将关系标记为已更改,以便EF生成插入?

EDMX详细信息:

    <AssociationSet Name="GeoBoundaryAssociation" Association="Contact.GeoBoundaryAssociation">
      <End Role="GeoBoundary" EntitySet="GeoBoundaries" />
      <End Role="GeoBoundary1" EntitySet="GeoBoundaries" />
    </AssociationSet>

    <Association Name="GeoBoundaryAssociation">
      <End Type="Contact.GeoBoundary" Role="GeoBoundary" Multiplicity="*" />
      <End Type="Contact.GeoBoundary" Role="GeoBoundary1" Multiplicity="*" />
    </Association>

2 个答案:

答案 0 :(得分:1)

您需要确保您的导航属性已附加到当前的DBContext。否则EF会忽略它。

试试这个:

...

//get a reference to the parent geoboundary for this entry
GeoBoundary parent = contactContext.GeoBoundaries
    .include("GeoBoundaryAssocTo")
    .FirstOrDefault(x => x.GeoID == entry.Key);

...
// You may need to use include on your child entity too.

答案 1 :(得分:0)

嗯,我是我自己困境的根源。我没有意识到我正在重用我的contactContext(实例化为服务类),并且在早期方法方法调用中我设置了AutoDetectChangesEnabled = false;。我需要做的就是重新打开更改跟踪。不知何故,我从未想到服务类已经保持了之前调用的状态。生活和学习。