Entity Framework多对多关系问题:EF重复创建已有实体行
解决EF多对多关系中重复创建已有实体的问题
这个问题我之前也碰到过,核心原因就是EF没把你选中的Objetivos识别成数据库里已有的实体,反而把它们当成全新的来处理了。给你几个靠谱的解决办法:
方法一:用Attach标记已有实体
如果你已经知道选中的Objetivos的ID,不需要从数据库查询实体的其他属性,可以直接创建一个只包含ID的Objetivos实例,然后用Attach方法告诉EF:“这个实体已经在数据库里了,别再新建了”。
代码示例:
// 假设你拿到了用户选中的Objetivos ID列表(5到8) var selectedObjetivoIds = new List<int> { 5, 6, 7, 8 }; var newRedes = new Redes(); foreach (var id in selectedObjetivoIds) { // 创建仅包含主键的实体实例 var existingObjetivo = new Objetivos { Id = id }; // 标记该实体为数据库中已存在的状态 _context.Attach(existingObjetivo); // 关联到新的Redes实例 newRedes.Objetivos.Add(existingObjetivo); } // 添加新Redes到上下文并保存 _context.Redes.Add(newRedes); await _context.SaveChangesAsync();
方法二:用Find获取已跟踪的实体
如果你需要获取Objetivos的完整属性,或者担心ID不存在的情况,可以用Find方法从上下文(或数据库)中获取实体。Find会先检查上下文是否已经跟踪该实体,如果没有再去数据库查询,获取到的实体自动被EF跟踪,不会被当成新实体。
代码示例:
var selectedObjetivoIds = new List<int> { 5, 6, 7, 8 }; var newRedes = new Redes(); foreach (var id in selectedObjetivoIds) { // 从上下文/数据库获取已存在的Objetivos var existingObjetivo = await _context.Objetivos.FindAsync(id); if (existingObjetivo != null) { newRedes.Objetivos.Add(existingObjetivo); } } _context.Redes.Add(newRedes); await _context.SaveChangesAsync();
额外注意点
- 确保你的
Objetivos实体的主键配置正确(比如自增主键的话,不要手动设置非默认值的主键,除非是已存在的实体)。 - 如果是通过DTO传递数据,不要直接把DTO转换成实体就添加到上下文,一定要处理成EF能识别的“已存在”状态(用上面两种方法)。
内容的提问来源于stack exchange,提问作者Caio Sant'Anna
相关产品推荐
相关产品推荐

