EF6中如何将多对多导航属性标记为未修改状态?
解决EF6多对多集合导航属性手动赋值后避免更新关联表的问题
在EF6中,多对多关系的关联状态是独立于实体属性的,无法通过设置集合属性的IsModified来控制,需要直接修改关联关系的跟踪状态:
具体步骤与代码实现
- 确保关联的Material实体已被上下文跟踪:如果你的Material是通过
AsNoTracking()查询的,需要先将其附加到上下文,让EF识别它是已存在的实体。 - 修改Order与Material的关联关系状态:将每一对Order-Material的关联状态设置为
Unchanged,告诉EF这些关联不需要被更新。
示例代码:
// 假设order是已加载的Order实体,且已手动赋值order.Materials为筛选后的物料列表 using (var context = new YourDbContext()) { // 先附加Order到上下文(如果还没被跟踪的话) if (context.Entry(order).State == EntityState.Detached) { context.Orders.Attach(order); } // 附加所有Material到上下文,确保EF识别它们是数据库中已有的记录 foreach (var material in order.Materials) { if (context.Entry(material).State == EntityState.Detached) { context.Materials.Attach(material); } } // 将Order与每个Material的关联状态设置为Unchanged var orderEntry = context.Entry(order); foreach (var material in order.Materials) { context.ObjectStateManager.ChangeRelationshipState( order, material, o => o.Materials, EntityState.Unchanged ); } // 此时调用SaveChanges()不会更新多对多映射表 context.SaveChanges(); }
原理说明
EF6会将多对多的关联关系作为独立的条目在ObjectStateManager中跟踪。当你手动赋值Materials集合时,EF默认会将这些关联标记为Added状态,导致SaveChanges()时向关联表插入新记录。通过ChangeRelationshipState将关联状态改为Unchanged,EF就会认为这些关联是已存在的,不会执行任何增删操作,和使用.Include()自动加载的效果完全一致。
内容的提问来源于stack exchange,提问作者Codisattva
相关产品推荐
相关产品推荐

