加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 在不使用导航属性的情况下添加相关实体

发布时间:2020-12-16 02:02:06 所属栏目:百科 来源:网络整理
导读:我有以下类,设置为测试: public class Company{ [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } public string Name { get; set; }}public class Employee{ [DatabaseGenerated(DatabaseGeneratedOption.Identity)] p
我有以下类,设置为测试:

public class Company
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Employee
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public string Name { get; set; }

    public int CompanyId { get; set; }
    public virtual Company Company { get; set; }
}

public class EFTestDbContext : DbContext
{
    public DbSet<Employee> Employees { get; set; }
    public DbSet<Company> Companies { get; set; }
}

为了测试,我想通过单个SaveChanges调用为该公司插入一个公司和一个员工,如下所示:

Company company = new Company
{
    Name = "Sample company"
};

context.Companies.Add(company);

// ** UNCOMMENTED FOR TEST 2
//Company company2 = new Company
//{
//    Name = "Some other company"
//};
//context.Companies.Add(company2);

Employee employee = new Employee
{
    Name = "Hans",CompanyId = company.Id
};
context.Employees.Add(employee);

context.SaveChanges();

虽然我没有使用导航属性,但是我已经与Id建立了关系,这在某种程度上是神秘的 – 员工用适当的外键保存到公司,从0更新到实际价值,这让我走了?!?!一些隐藏的C#功能?

然后我决定添加更多代码,在上面的代码段中注释,使其插入2 x Company实体和1 x Employee实体,然后我得到异常:

Unable to determine the principal end of the ‘CodeLab.EFTest.Employee_Company’ relationship. Multiple added entities may have the same primary key.

这是否意味着在外键为0并且在同一个SaveChanges事务中插入单个匹配实体的情况下,实体框架将假定外键应该用于该匹配实体?

在第二个测试中,当有两个实体匹配关系类型时,实体框架会抛出异常,因为它无法确定应该与哪个公司员工相关联.

编辑:

我做了一个测试,并注释掉了一行.第一个测试仍然正常运行(因为int的默认值为0):

Employee employee = new Employee
{
    Name = "Hans",//CompanyId = company.Id // * no need for this at all
};

解决方法

你并没有真正触及隐藏的C#功能,可能是一个不起眼的实体框架功能.

当您分配CompanyId时,EF知道Id = 0(当时)的公司是员工的父母.在很多场合,EF executes DetectChanges,它还执行关系修复:匹配外键值和引用.执行时会发生这种情况

context.Employees.Add(employee);

现在EF将使用引用而不是外键值,因此它知道要在数据库中存储哪个FK值.

当您创建两个公司时,有两个实例具有相同的临时键值,因此EF不能再选择.

因此,当您想要存储新的连接对象时,始终建议设置引用而不是FK值.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读