如何在EF6中无需加载数据即可删除多对多集合关联项
EF6 无需加载关联集合操作多对多关联项方案
EF6原生支持无需加载全量关联数据即可完成多对多关联项的增删,全程不会触发额外SELECT查询,仅会生成对应中间表的INSERT/DELETE语句。
核心原理
全程不触发关联集合的懒加载:懒加载仅在你访问关联集合的get方法时触发,只要操作过程中不读取关联集合的值,同时手动将待操作的实体作为存根Attach到上下文,即可跳过全量数据加载。
新增关联示例
以下示例默认你的Book、Category类都包含名为Id的int类型主键(与你代码中Find(1)、Find(5)的入参对应),如果主键名不同请自行替换,仅需知道两个关联实体的主键值即可操作,无需查询数据库获取完整实体:
// 1. 创建存根实体,仅赋值主键即可 var book = new Book { Id = 1 }; var actionCategory = new Category { Id = 5 }; // 2. 将实体Attach到上下文,标记为已存在的未修改实体,此步骤不会查询数据库 dbContext.Books.Attach(book); dbContext.Categories.Attach(actionCategory); // 3. 初始化关联集合(仅new不会触发懒加载),添加关联 book.Categories = new List<Category>(); book.Categories.Add(actionCategory); // 4. 保存,仅生成1条插入中间表的INSERT语句,无其他查询 dbContext.SaveChanges();
删除关联示例
推荐直接操作关系状态,无需修改集合即可完成删除,彻底避免触发懒加载:
// 1. 同样仅需创建主键正确的存根实体 var book = new Book { Id = 1 }; var actionCategory = new Category { Id = 5 }; // 2. Attach实体到上下文 dbContext.Books.Attach(book); dbContext.Categories.Attach(actionCategory); // 3. 直接标记多对多关联为删除状态,无需操作关联集合 ((IObjectContextAdapter)dbContext).ObjectContext .DeleteRelationship(book, b => b.Categories, actionCategory); // 4. 保存,仅生成1条删除中间表对应记录的DELETE语句,无其他查询 dbContext.SaveChanges();
注意事项
- 操作前确保传入的主键值在数据库中真实存在,否则会触发外键约束报错
- 不要在Attach操作前访问关联集合的属性值,否则会直接触发懒加载查询
- 若对应实体已经被当前上下文跟踪,无需重复执行Attach操作,直接操作即可
内容的提问来源于stack exchange,提问作者Peter Dandy
相关产品推荐
相关产品推荐

