【问题标题】:EF 4.1 with DbContext-based POCO objects is not lazy-loading internal navigation properties带有基于 DbContext 的 POCO 对象的 EF 4.1 不是延迟加载内部导航属性
【发布时间】:2011-05-03 14:02:48
【问题描述】:

我正在开发一个 CRM 风格的 MVC Web 应用程序,它具有以下(简化的)架构:

联系人表

  • 联系人 ID
  • 名字
  • 姓氏

标签表

  • 标签ID
  • 价值

ContactTags 表

  • 联系人 ID
  • 标签ID

然后,我从 *.edmx 文件生成 POCO 对象,与基于 DbContext 的实体上下文交互,隐藏 ContactTags 表,以便将 Contact 和 Tag 实体之间的关系建模为多对多关联。然后,我限制了对原始 Contact.Tags 导航属性的访问,将其设置为内部而不是公共的,并公开了一个 ReadOnlyCollection,它可以在域层之外用于显示标签,但将集合上的数据操作限制为联系人.EditTags() 方法。

在编写 UI 代码以显示联系人的标签列表时,我发现标签导航属性没有被延迟加载。在挠了挠头并谷歌搜索了一下之后,我在EF CTP4 lazy loading not playing ball 找到了另一个与我的问题相匹配的问题。问题的作者发现,当他将内部属性更改为公开时​​,它开始工作,果然这也是发生在我身上的事情 - 我已将标签导航属性更改为公开,现在它正在工作。

从对象建模/数据封装的角度来看,我对此感到不舒服,因为不应授予 UI 访问原始标签集合的权限,这将使控制器代码能够调用 Tags.Add()、Tags.Remove等。

有谁知道这是一个错误,还是 EF 团队经过深思熟虑的设计决定?是否可以让内部导航属性延迟加载?我知道我们可以预先加载,但我们希望尽可能避免这种情况。

【问题讨论】:

    标签: asp.net-mvc-3 entity-framework-4.1


    【解决方案1】:

    延迟加载 POCO 需要创建 POCO 代理。仅当模型类满足某些要求时才会创建代理。启用延迟加载的代理的这些要求之一是:

    每个导航属性都必须是 声明为 public、虚拟 (在 Visual Basic 中可重写),而不是 密封(Visual 中的 NotOverridable 基本)获取访问器。

    从这里引用:http://msdn.microsoft.com/en-us/library/dd468057.aspx

    【讨论】:

    • 感谢您的回答 - 当您这样说时,这是有道理的,我明白为什么需要这样。猜猜我忘记了延迟加载,然后在这种情况下进行急切加载!
    • @jsidnell:顺便说一句:我玩过一些内部属性和急切加载,发现似乎有必要在 Fluent API 中指定每个内部标量和导航属性。例如,当我没有在 Fluent API 中指定列时,内部标量属性被简单地从模型中排除(没有创建数据库列)。似乎有一个约定说:如果属性不是公共的,则将其从模型中排除,除非 Fluent API 明确定义了该属性。就像当您使用内部属性进行预加载时的提示一样。
    猜你喜欢
    • 2011-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多