【问题标题】:Entity Framework - An item with the same key has already been added. - Error when trying to define foreign key relationship实体框架 - 已添加具有相同键的项目。 - 尝试定义外键关系时出错
【发布时间】:2010-08-30 06:58:31
【问题描述】:

我有一个与 asp.net 会员提供者用户表有外键关系的实体。

这部分模型如下所示:

在插入用户表记录时,我似乎无法分配外键关系,该记录包含aspnet_Users 表的外键。我不断收到错误:

具有相同密钥的项目已经 已添加。

我使用的代码如下:

UserAdmin userToAdd = new UserAdmin();
...
userToAdd.aspnet_Users = membershipUser;
//line above OR line below
userToAdd.aspnet_UsersReference.EntityKey = new System.Data.EntityKey("ProjectEntities.aspnet_Users", "UserId", membershipUser.UserId);

db.AddToUsers(userToAdd);
db.SaveChanges();

当该记录已经存在时,我要求 EF 添加新的aspnet_Users 表记录(关联主键表的记录)的问题是什么?

如何将外键值分配给已经存在主键记录的实体?

更新的测试代码块:

MembershipUser membershipUser = Membership.CreateUser("blah@blah.com", "pass", "blah@blah.com");

Entities db = new Entities();
UserAdmin newUser = new UserAdmin();
newUser.Name = "blah";
newUser.DateAdded = DateTime.Now;

Guid key = new Guid(membershipUser.ProviderUserKey.ToString());
aspnet_Users membershipUserRecord = db.aspnet_Users.Where(u => u.UserId == key).FirstOrDefault();
newUser.aspnet_Users = membershipUserRecord;
//newUser.aspnet_UsersReference.EntityKey = new System.Data.EntityKey("Entities.aspnet_Users", "UserId", membershipUserRecord.UserId);
db.ObjectStateManager.ChangeObjectState(membershipUserRecord, EntityState.Unchanged);

db.AddToUsers(newUser);
db.SaveChanges();

此代码生成错误:

已添加具有相同密钥的项目。

【问题讨论】:

  • membershipUser 是否被(相同的)DataContext 跟踪?
  • 是的,membershipUser 记录由用于提交新用户记录的同一实体模型实例检索。

标签: .net linq entity-framework linq-to-entities entity-framework-4


【解决方案1】:

好的,我想出了这个。像往常一样,只是我犯了一个错误,没有马上抓住它,因为我找错了地方。

问题是由于我的表继承和数据库级别的配置。我将子表的(UserAdmin)外键字段定义为身份,然后在我的模型中显示为 StoreGeneratedPattern = Identity。当 EF 尝试将父项的主键传播到其子项的外键字段时,这会导致“已添加具有相同键的项目错误”。

一旦我从 UserAdmins 表中删除了身份规范,问题就消失了。

问题解决了。

【讨论】:

    【解决方案2】:

    是的,这正是问题所在。你是如何获得membershipUser实体的?如果你没有从当前的 ObjectContext 中得到它,EF 认为它是新的,它会尝试将它插入到 aspnet_users 表中。

    将用户添加到 ObjectSet 后尝试使用此代码:

    // db is ObjectContext instance
    db.ObjectStateManager.ChangeObjectState(membershipUser, EntityState.Unchanged);
    

    可能还有其他方法可以达到相同的结果,但这对我有用。

    【讨论】:

    • 我尝试使用 ChangeObjectState() 但无济于事,仍然收到“已添加具有相同密钥的项目”错误。我已在原始帖子中添加了我的测试代码外观。
    • 我检查了你的代码,它应该可以工作。此外,当您通过 EF 选择 aspnet 用户时,您不需要设置其状态 - 它已经处于未更改状态。用户表是空的吗?用户表中的 UserId 是自动生成的吗?如果您使用 SQL Server 并且安装了 SQL Profiler,则可以检查执行了哪些 SQL 命令。
    • 我已经在数据库上运行了一个配置文件,但在成员资格提供程序执行 Membership.CreateUser() 之后,我似乎没有看到任何插入语句。调用 SaveChanges() 似乎根本不会对数据库执行任何插入或更新语句。
    • 似乎在将更改推送到数据库之前,对象集合中发生了错误:[ArgumentException: An item with the same key has been added.] System.Collections.Generic.Dictionary` 2.Insert(TKey key, TValue value, Boolean add) +12753120 System.Data.Mapping.Update.Internal.UpdateCommandOrderer.AddServerGenDependencies() +232 [UpdateException: 在多个位置生成跨实体或关联共享的值。检查映射是否不会将 EntityKey 拆分为多个存储生成的列。]
    猜你喜欢
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    • 2020-11-23
    • 2015-08-01
    • 2021-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多