考虑以下模型:
public class Car
{
public virtual Company Company { get; set; }
public virtual string CompanyId { get; set; }
}
据我所知,Company
和CompanyId
应按惯例同步。因此,设置Company
属性会导致自动设置CompanyId
。所以下面的测试应该通过:
myCar.Company = new Company() { Id = "11" };
Assert.AreEqual("11", myCar.CompanyId);
为什么会这样?
我的DbContext配置是:
Configuration.LazyLoadingEnabled = false;
Configuration.ProxyCreationEnabled = false;
答案 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。