Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 违反实体框架代码第一链接表中的主键约束_C#_.net_Entity Framework_Ef Code First - Fatal编程技术网

C# 违反实体框架代码第一链接表中的主键约束

C# 违反实体框架代码第一链接表中的主键约束,c#,.net,entity-framework,ef-code-first,C#,.net,Entity Framework,Ef Code First,我有一个用户表和一个角色表。有一个自动生成的UsersRoles链接表,其中包含来自User和Roles表的Id。这是使用以下代码生成的: modelBuilder.Entity<User>() .HasMany(u => u.Roles) .WithMany(r => r.Users) .Map(c => { c.MapLeft

我有一个用户表和一个角色表。有一个自动生成的UsersRoles链接表,其中包含来自User和Roles表的Id。这是使用以下代码生成的:

modelBuilder.Entity<User>()
                .HasMany(u => u.Roles)
                .WithMany(r => r.Users)
                .Map(c => { 
                    c.MapLeftKey("UserId");
                    c.MapRightKey("RoleId");
                    c.ToTable("UsersRoles");
                });

有人知道为什么会发生这种情况吗?

具有
UserId=2beaf837-9034-4376-9510-b1609c54efbe
User
和具有
RoleId=dcd16d00-d46e-4d48-8328-3e7b35b11ccf
角色处于状态的事实并不意味着没有写入数据库

特别是对于多对多关系(通常用于独立关联),EF为关系本身维护一个不同于实体状态的状态。如果一个条目被插入到链接表中,这意味着两个实体的关系条目处于状态
Added
,尽管这些实体的实体状态是
Unchanged
。枚举
DbContext
s
ChangeTracker
时,无法看到关系条目。它将只返回实体状态。您必须进入底层的
ObjectContext
查询关系状态

例如:

using (var ctx = new MyContext())
{
    var user = ctx.Users.Find(1);
    var role = ctx.Roles.Find(5);

    user.Roles = new List<Role>();
    user.Roles.Add(role);

    ctx.SaveChanges();
}
使用(var ctx=new MyContext())
{
var user=ctx.Users.Find(1);
var-role=ctx.Roles.Find(5);
user.Roles=新列表();
user.Roles.Add(角色);
ctx.SaveChanges();
}
此处
用户
角色
都将处于状态
未更改
,但仍会在链接表中插入一条记录。如果数据库中已经链接了用户1和角色5,则此代码将引发异常


添加
与问题无关。只有对
SaveChanges
的调用才会导致异常,因为您很可能在问题中的代码片段之前的某个位置创建了两个实体之间的关系。

您正在尝试将相同的用户/角色组合插入到UserRoles表中:

违反主键约束“PK_UsersRoles”。无法在对象“dbo.UsersRoles”中插入重复键。重复的键值为(2beaf837-9034-4376-9510-b1609c54efbe,dcd16d00-d46e-4d48-8328-3e7b35b11ccf)。该语句已终止。

检查哪个用户的ID为2beaf837-9034-4376-9510-b1609c54efbe,哪个角色的ID为dcd16d00-d46e-4d48-8328-3e7b35b11ccf。
如果您确定只输入了该用户一次,那么该方法是否会在您未意识到的情况下插入被多次调用的数据?

要添加到Slauma的答案中,看起来如果您在这些自动多对多功能之一上设置ICollection属性,EF感到困惑,并没有意识到这样做是在清除集合元素

因此,与其这样做,不如:

user.Roles = new List<Role>();
user.Roles.Add(role);
这对我有用


不过你不应该这么做。这应该是EF中的一个bug。

希望有人会发现它有帮助。我发现在EF中更改现有列表与创建新列表之间有很大的区别

在本例中,我正在进行更新,并认为创建一个我想要的项目的新列表是最简单的。但是,如果某些项已经添加到列表中,则在保存时会出现主键冲突


最后,我保留了相同的列表,只是对其进行了修改。清除它并读取是可以的,创建一个新列表则不是。

您应该发布将实体添加到上下文的代码。您能准确显示您所检查的内容吗?我怀疑您只验证了
角色
用户
实体未更改。感谢您提出的问题,我已更新了我的问题以添加更多信息。希望能有帮助。你是说
Context.Set().Add(group)?我还是不明白。添加角色组如何导致违反无关UserRoles表中的主键?这里也有同样的问题。绝对应该被认为是一个bug。这里也有同样的问题。在我的例子中,我在每个继承人配置的表中的子对象上有一个导航属性。为了让它正常工作,我必须通过DbContext.Entry(entity.Collection)(x=>x.children.load())手动加载实体的子级。仅仅通过查询加载它们是不够的。然后要更新列表,我必须清除并添加新条目。
user.Roles = new List<Role>();
user.Roles.Add(role);
user.Roles.Clear();
user.Roles.Add(role);