2011-05-03 27 views
1

我工作的一个CRM风格的MVC的Web应用程序,它具有以下(简化)架构:EF 4.1基于的DbContext,POCO的对象是不懒加载内部导航性能

联系人表

  • 的ContactID
  • 用的名字
  • 等等

标签表

  • 标签识别
  • 价值

ContactTags表

  • 的ContactID
  • 标签识别

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

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

我从视图中的对象的建模/数据封装点不舒服与此,由于UI不应给予访问原始标签集合这将使控制器的代码来调用Tags.Add(),标签。删除等

有没有人知道这是一个错误,还是EF团队的故意设计决定?是否有可能获得内部导航属性延迟加载?我知道我们可以急切加载,但如果可能的话,我们希望避免这种情况。

回答

4

对POCO的延迟加载需要创建POCO代理。代理仅在模型类符合特定要求时才创建。其中一个用于代理这使延迟加载这些要求是这样的一个:

每个导航属性必须 声明为公共,虚拟 (可重写在Visual Basic中),而不是 密封(NotOverridable在Visual 基本)获得访问者。从这里

报价:http://msdn.microsoft.com/en-us/library/dd468057.aspx

+0

感谢您的答案 - 当你这样说的话,这是有道理的,我可以看到为什么它需要这样。猜猜我忘记了延迟加载,然后在这种情况下进行热切加载! – jonsidnell 2011-05-04 08:04:20

+1

@jsidnell:顺便说一句:我曾经玩过一些内部属性和急切的加载,发现似乎有必要在Fluent API中指定每个内部标量和导航属性。例如,当我没有在Fluent API中指定列时,内部标量属性完全从模型中排除(没有创建数据库列)。似乎有一个惯例说:如果一个属性不公开,则将其从模型中排除,除非Fluent API明确定义该属性。就像你移动到渴望加载你的内部属性时的提示一样。 – Slauma 2011-05-04 09:25:01