我有一个实体BusinessUnit,它与Contact实体有多对多的关系。我们按照以下示例使用Fluent配置:
public BusinessUnitConfiguration()
{
HasMany(c => c.Contacts)
.WithMany()
.Map(m =>
{
m.ToTable("BusinessUnitContact");
m.MapLeftKey("BusinessUnitId");
m.MapRightKey("ContactId");
});
ToTable("BusinessUnit");
}
public ContactConfiguration()
{
ToTable("Contact");
}
联络实体不知道它可能与哪些父母有关。我们正在使用Silverlight + WCF,因此禁用了延迟加载和代理创建。
我们在客户端上创建或修改一个对象图,该对象图包含一个BusinessUnit实例和零个或多个Contact实例,然后发送到WCF服务进行保存,创建新的上下文,并在必要时添加/附加/删除保存更改。
问题是,如果我在现有业务部门的Contacts集合中添加新联系人,EF不会插入联结记录 - 它知道要添加新联系人,因为我已经添加了它,但没有添加BusinessUnitContact将业务单位映射到联系人的行。
BusinessUnit上的Contacts属性是ObservableCollection< Contact>。它在添加父业务单位时有效,但在附加父业务单位时无效。
有什么方法可以告诉EF在将它附加到上下文时修改Contacts关联,这样就可以计算出需要插入哪些新的联结记录?
答案 0 :(得分:0)
我发现了问题。将父实体附加到EF上下文的代码实际上并没有直接附加它 - 它正在加载原始实体,然后合并来自附加实体的属性:
// attach entity
var existing = GetQuery<TEntity>().FirstOrDefault(e => e.Id == entity.Id);
if (existing == null)
{
throw new InvalidOperationException("Cannot attach an entity that does not exist in the database.");
}
switch (entity.State)
{
case ObjectState.Modified:
GetEntry(existing).CurrentValues.SetValues(entity);
break;
case ObjectState.Deleted:
GetEntry(existing).State = EntityState.Deleted;
break;
}
这似乎不适用于导航属性,因此我将代码更改为以下内容:
var set = GetSet<TEntity>();
set.Attach(entity);
// map object state to entity state
switch (entity.State)
{
case ObjectState.Modified:
GetEntry(entity).State = EntityState.Modified;
break;
case ObjectState.Deleted:
GetEntry(entity).State = EntityState.Deleted;
break;
}
所有需要改变的是确保附加的实体与进入的实体相同 - 也不必修改BusinessUnit实体。