【问题标题】:Adding new child records to a parent table in entity framework 6在实体框架 6 中向父表添加新的子记录
【发布时间】:2014-10-11 21:52:18
【问题描述】:

我有 3 张桌子:

帐户:ID、姓名

用户:ID、AccountId、姓名

用户详情:Id、UserId、电话

实体:

public partial class Account
{
    public Account()
    {
        this.Users = new HashSet<User>();
    }

    public int Id{get;set;}
    public string Name{get;set;}
    public virtual ICollection<User> Users{get;set;}
}

public partial class UserDetail
{
    public int Id{get;set;}
    public string Phone {get;set;}
    public virual User User {get;set;}
}

public partial class User
{
    public User()
    {
        this.Accounts = new HashSet<Account>();
    }

    public int Id{get;set;}
    public virtual ICollection<Account> Accounts {get;set;}
    public virtual UserDetail UserDetail{get;set;}
}

如您所见,Account to User 是一对多的关系,因此我的 Account 实体具有 Users DbSet。而 User 到 UserDetail 是一对一的关系。

我目前正在尝试将用户和用户详细信息记录插入现有帐户。所以我的代码如下所示:

var newUserDetail = new UserDetail();
newUserDetail.Phone = 014109842;

var newUser = new User();
newUser.Name = "John Smith";
newUser.UserDetail = newUserDetail;

var currentAccount = _dbContext.Accounts.First(a => a.Id == 100);
currentAccount.User.Add(newUser);
_dbContext.SaveChanges();

我收到以下错误: “ReferentialConstraint 中的依赖属性映射到存储生成的列。列:'Id'。”

想法?

【问题讨论】:

  • 如果提供 Account、User 和 UserDetail 的类定义,您将获得更多帮助。
  • @EtihwSirhc 我现在做了

标签: entity-framework-6 referential-integrity


【解决方案1】:

ReferentialConstraint 中的依赖属性映射到存储生成的列。列:“ID”

我更详细地研究了这个错误并发现了这个帖子:A dependent property in a ReferentialConstraint is mapped to a store-generated column

基本上,它表示 UserDetail.Id(它是依赖属性)具有引用约束,并且也是存储生成的列,即自动增量。

解决方案是删除自动增量属性,或者在 User 到 UserDetail 或在 UserDetail 到 User 上添加不同的 FK。

经验教训: 1.肯定有带有类/表名称的标识列。例如,如果可以,请将您的身份 (PK) 列命名为表名作为前缀。所以在我的问题中,我真的应该将所有 Id 列重命名为 AccountId、UserId、UserDetailId。

为什么?

EF 的内部异常会给我一个明显的线索来查看 UserDetailId 上的映射。没有这个,我一直想知道哪个映射是有问题的。

【讨论】:

    【解决方案2】:

    试试这个。

    var newUserDetail = new UserDetail();
    newUserDetail.Phone = 014109842;
    _dbContext.UserDetail.Add(newUserDetail);
    
    var newUser = new User();
    newUser.Name = "John Smith";
    _dbContext.User.Add(newUser);
    
    _dbContext.saveChanges(); // save changes so the db can generate ID's
    
    newUser.UserDetail = newUserDetail;
    
    var currentAccount = _dbContext.Accounts.First(a => a.Id == 100);
    currentAccount.User.Add(newUser);
    _dbContext.SaveChanges();
    

    【讨论】:

    • 我应该提到这是一个 DB first EF 模型,对不起!我无法更改模型。帐户表没有用户表的外键。用户表有一个 AccountId 映射到 Account 表的 Id。 EF 模型生成器创建了映射。
    • 对,这就是我不问的结果。更新了我的答案。
    • 这个想法确实闪过我的脑海,但我想知道是否可以在不使用 Account 控制器中的另一个 UserService 类的情况下逃脱(如果你知道我的意思的话)。另外,我正在使用工作单元模式,如果我这样做会破坏。
    • 假设您拥有的代码有一个工作单元,我看不出它有什么问题。您可以将其包装在事务中 using (var transaction = context.Database.BeginTransaction()) { try { &lt;&lt;your code here&gt;&gt; transaction.Commit(); } catch (Exception) { transaction.Rollback(); } }
    • 发现问题了! User 和 UserDetail 之间的关系映射是问题所在。 UserDetail.Id 是一个自动增量标识列,并且 UserDetail.Id 被映射到 User.Id。保存用户时,UserDetail.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多