.net EF代码中的多对多关系有什么问题

.net EF代码中的多对多关系有什么问题,.net,entity-framework,entity-framework-6,.net,Entity Framework,Entity Framework 6,我正在首先编写代码EF6.0,并试图实现请求表和标记表之间的多对多关系 这些关系被正确设置为: HasMany(b => b.Tags).WithMany().Map(mc => mc.MapLeftKey("RequestID").MapRightKey("TagID").ToTable("requesttags")); 一切看起来都很好。但是,在根据请求插入标记时,我会以三种方式插入: > if (request.Tags == null) >

我正在首先编写代码EF6.0,并试图实现请求表和标记表之间的多对多关系

这些关系被正确设置为:

HasMany(b => b.Tags).WithMany().Map(mc => mc.MapLeftKey("RequestID").MapRightKey("TagID").ToTable("requesttags"));
一切看起来都很好。但是,在根据请求插入标记时,我会以三种方式插入:

>   if (request.Tags == null)
>             {
>                 entity.Tags = new List<Tag>();
>             }
>              // 1 way get the tag and then insert.
>             var tag = _tagService.Get(1);
               // 2 and 3 way hard code id with the name. 
>             var tags = new List<Tag> {tag, new Tag {Name = ".Net", ID = 2}, new Tag {Name = "C#"}};
> 
>             request.Tags.AddRange(tags);
>如果(request.Tags==null)
>             {
>entity.Tags=新列表();
>             }
>//1路获取标记,然后插入。
>var tag=_tagService.Get(1);
//带有名称的2路和3路硬代码id。
>var tags=new List{tag,new tag{Name=“.Net”,ID=2},new tag{Name=“C#”};
> 
>request.Tags.AddRange(标签);
执行插入操作。但是,当我看到最终结果时:第一个标记正确地进行了引用。然而,对于两个标记,即使ID和名称匹配,它仍然在标记表中创建一个新记录并进行引用

我的想法是,第一个标记对象是从数据库中获取的,它是附加的。但是为什么我必须附加

我怎样才能解决这个问题

但是为什么我必须附加

因为它们是断开连接的对象,将被视为新对象。当您将
标记添加到
请求.tags
中时,它们都将被标记为已添加,因为EF不知道它们都是现有实体

只需循环
标记
,即可检查每个标记的状态

request.Tags.AddRange(tags);
foreach(var tag in tags)
{
    Console.WriteLine(dbContext.Entry(tag).State);
}
输出应如下所示:

Unchanged
Added
Added
我怎样才能解决这个问题

对于断开连接的对象,只需
附加它或将其标记为
未更改

dbContext.Entry(tags[1]).State = EntityState.Unchanged;
// equals to dbContext.Set<Tag>().Attach(tags[1]);
dbContext.Entry(tags[2]).State = EntityState.Unchanged;
// equals to dbContext.Set<Tag>().Attach(tags[2]);
dbContext.Entry(标记[1]).State=EntityState.Unchanged;
//等于dbContext.Set().Attach(标记[1]);
条目(标记[2]).State=EntityState.Unchanged;
//等于dbContext.Set().Attach(标记[2]);

并确保这两个实体都是真实存在的实体,如果不是,则调用
SaveChanges

时将抛出
DbUpdateException
,谢谢您的时间。我理解,我也将遵循同样的原则。然而,我的印象是,有一些应用程序范围的方法来管理它。换句话说,我的所有实体都有一个名为ID的字段,如果我能告诉EF,嘿,这就是在插入/更新之前要检查和查找的字段。这样我就不必循环并更改状态。@基于代码,EF无法知道每个断开连接的对象的状态,EF只会将它们视为新对象,即使ID不是0或Guid不是空的,在这种情况下仍会添加它们。实体框架负责跟踪实体连接到上下文时的状态,但在断开连接或N层场景中,您可以让EF知道您的实体应该处于什么状态。如果您正在寻找一个优雅的解决方案,您可以使用