【问题标题】:EF6: Forcing Navigation Property to load after setting FK PropertyEF6:设置 FK 属性后强制导航属性加载
【发布时间】:2016-04-18 13:36:32
【问题描述】:

我终于从 EF 4.5 升级到 EF 6.1,但我遇到了一些我无法克服的不同行为。我正在使用数据库优先设计。

我有一个带有 CompanyID FK 属性和 Company 导航属性的 Person 表:

public partial class Person
{
    ... other properties ...
    public int CompanyID { get; set; }
    public virtual Company Company { get; set; }
}

当我使用语法加载一个人对象时

dbcontext.Persons.FirstOrDefault(p => p.Id == id)

返回的 person 对象设置了 CompanyID,并且 Company 属性按预期延迟加载(我使用 Database.Log 输出生成的 SQL 并验证 Company 是延迟加载的)。

我的问题是 CompanyID 最初为空。如果我设置它的值,我不能让 Company 属性基于新的 CompanyID 值延迟加载。这在 EF4.5 中有效,所以我希望在 EF6 中有类似的方法来获得相同的行为。

有什么想法吗?提前致谢。

* 已编辑 * 我忘记在上面的代码示例中的 Company 属性中包含“virtual”关键字。

【问题讨论】:

  • 你确定你的类是懒加载的吗?我在那里没有看到任何 virtual 关键字。
  • 我很确定。我连接了 DBContext.Database.Log 方法以输出到控制台,这样我就可以看到生成的 SQL 和数据库调用。调用 dbcontext.Persons.FirstOrDefault 方法会导致仅针对 Person 表的 select 语句,然后访问 Company 属性会为 Company 表生成一个 select statemetn。因此,只要最初设置了 CompanyID 属性,就会延迟加载 Company 属性。
  • dbcontext.Persons.Include(p => p.Company).FirstOrDefault(p => p.Id == id) 怎么样?
  • 想必您在设置 CompanyID 之后并在引用 Company 属性之前调用了 SaveChanges()
  • 我没有,并且希望有办法不必先调用 SaveChanges()。我之前在 EF4.5 中没有,所以我现在必须在 EF6 中获取导航属性以在 FK 字段更新后自行更新吗?

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


【解决方案1】:

不幸的是,您是对的,EF6 中似乎存在一些奇怪的延迟加载行为。

对于其他读者,这里有两个场景显示了两种(都是不正确的)行为。假设数据库包含 2 条 Company 记录,Id = 1 和 2,Customer 记录,CompanyId = 1。

(A)

var e = db.Employees.FirstOrDefault(x => x.Id == 1);
e.CompanyId = 2;
var c = e.Company;

结果:变量c 包含null

(B)

var e = db.Employees.FirstOrDefault(x => x.Id == 1);
var c1 = e.Company;
e.CompanyId = 2;
var c2 = e.Company;

结果:变量c2c1 相同,并通过Id=1 引用Company

很遗憾,我只能建议您一种解决方法,而不是通用解决方案。解决方法是在更改 FK 属性后包含这样的调用:

e.CompanyId = 2;
db.Entry(e).Reference(x => x.Company).IsLoaded = false; // The "fix"
var c = e.Company; // Works

【讨论】:

  • 感谢您验证行为并为我提供解决方法。我很感激!
猜你喜欢
  • 1970-01-01
  • 2015-11-13
  • 2019-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多