为什么在实体框架中没有自动填充ForeignKeyId?

时间:2015-08-14 14:50:08

标签: c# entity-framework entity-framework-6

考虑以下模型:

public class Car
{
    public virtual Company Company { get; set; }
    public virtual string CompanyId { get; set; }
}

据我所知,CompanyCompanyId应按惯例同步。因此,设置Company属性会导致自动设置CompanyId。所以下面的测试应该通过:

myCar.Company = new Company() { Id = "11" };
Assert.AreEqual("11", myCar.CompanyId);

为什么会这样?

我的DbContext配置是:

Configuration.LazyLoadingEnabled = false;
Configuration.ProxyCreationEnabled = false;

3 个答案:

答案 0 :(得分:2)

如果您只是新建一个对象并将其添加到实体,那并不意味着EF已经注册了该对象并从数据库中进行了提取。您需要点击DbContext才能执行此操作。您可以使用任何可用的SQL分析工具来验证这一点。

答案 1 :(得分:2)

在实体框架中使用POCOs(普通旧类对象)时,"链接"您描述的属性只会在附加SaveChanges时调用DbContext时相互更新。正如您在课堂定义中所看到的那样,实际上没有"物理"属性之间的连接,因此更新一个不会直接更新另一个。

链接实际上由dbContext维护,只有在将更改保存到数据库后才会更新。即使这样,它在技术上也不会更新链接,而是从数据库中完全刷新对象。

作为一个额外的注释,.SaveChanges非常恰当地命名。它实际上存储了从db加载时属性的原始值,并按属性比较它们,查找更改的值,以便它知道要更新的内容。这可能是非常CPU和内存密集型。如果您只是在阅读数据并且知道您永远不会更新实例,那么您应该将.AsNoTracking()添加到您的linq查询中,以使其无法完成所有操作。

答案 2 :(得分:0)

从CompanyId中删除虚拟内容。

public class Car
{
    public virtual Company Company { get; set; }
    public string CompanyId { get; set; }
}

编辑:Bradley是对的,您必须保存更改才能查看链接的属性。 如果你想在保存之前访问id,你可以这样做;

var comp = new Company { Id = "11" };
ctx.Companies.Add(comp);

var car = new Car {
    Id = "2",
    CompanyId = comp.Id 
};
ctx.Cars.Add(car);

请记住,这样做必须将 comp car 添加到上下文中。 链接的属性 car.Company 将为null。