0

多年来,我一直在 ASP.Net 环境中使用 LINQ to SQL。UI 和 BLL 层由 Web 服务分隔,因此延迟加载、更改跟踪等不是一个选项。这在某种程度上很好,因为我们确切地知道代码中发生了什么——我们负责在 BLL 中持久更改(确定实体是否是新的/更新的),并且由于一些懒惰而没有意外的惊喜——加载在某处进行。

我现在已经转移工作并使用新的桌面系统 (WPF)。没有边界,即UI 层将直接调用 BLL(但请参阅最后的警告)。我正在寻找使用 EF5,但我对 EF 提供的功能、选项等的数量有点不知所措。我希望我能回答几个问题...

  1. 是否应该跨边界使用延迟加载?假设我想显示一个客户和他们的所有订单,UI 是否会只从 BLL 请求客户,然后使用延迟加载来访问其订单?在 UI 中执行此操作对我来说并不合适。我假设延迟加载只是您将在 BLL 中使用的东西。

  2. 我相信您可以使用 关闭延迟加载DbContext.Configuration.LazyLoadingEnabled,但是如果我想在我的 BLL 中使用延迟加载,但是当我将实体返回到我的 UI 时,我不希望 UI 进行任何延迟加载怎么办?

  3. 变更跟踪、自我跟踪实体和 POCO 怎么样?我应该在什么时候使用?当我使用 LINQ to SQL 时,这对我来说从来都不是问题(它跨越 Web 服务和 ASP.Net,因此没有“状态”,因此更改跟踪无关紧要)。我觉得我想全部停用它(这是我习惯的),但我担心我会错过一些 EF 的“优点”。我想我担心无法控制持久数据。

  4. 当我一直在使用 EF 进行操作和检索数据时,我注意到在一些实体层次结构中,一些属性集合(例如 customer.Orders)包含“代理”实体。这些是什么,它们什么时候有用?

  5. 我再次注意到您可以通过 关闭代理DbContext.Configuration.ProxyCreationEnabled,但文档表明它还有更多功能,并且与 LazyLoadingEnabled 设置有某种关系?

  6. EF“代码优先”似乎越来越受欢迎。它给了你什么?我习惯于在 SSMS 中设计我的数据库,而不是编写大量的类、注释等!

最后一个警告 - 虽然应用程序的 UI 层直接调用 BLL 中的方法,但将来我们可能希望将它们分开(例如通过 Web 服务)的可能性很小。这将如何影响设计考虑,以及我在上面提出的一些问题?

很抱歉将许多问题捆绑在一起。如果我能得到所有这些问题的答案,那么希望这对我将来遇到的其他人有用。

4

1 回答 1

1
  1. 在我看来,延迟加载旨在用于 UI 层而不是 BLL。它在数据绑定场景中特别有用,例如在主从视图中。如果您的 UI 中有客户列表,并且通过单击客户,用户可以显示客户的订单,这些订单可以通过延迟加载来加载。由于您事先不知道用户将点击哪些客户,因此如果您不想使用延迟加载(或实施您自己的事件驱动的子加载机制),您将被迫预先加载所有客户的所有订单)。这会产生不必要的开销。

    另一方面,我不明白为什么 BLL 中的延迟加载会很有趣。通常,您知道必须加载哪些数据才能执行特定的业务逻辑。当您知道它时,您可以使用急切或显式加载。与仅访问导航属性并依赖延迟加载相比,要编写一两行代码,但是通过急切和显式加载,您的代码做什么以及何时访问数据库是很清楚的。

    当然请记住,延迟加载需要一个尚未释放的上下文,因此您必须以一种只要您的 UI(或 UI 的一部分)被使用,上下文就存在的方式来设计 BLL。

  2. 如果您不想在 UI 层中进行延迟加载,请将其关闭并在 BLL 中使用急切和显式加载。一旦加载了启用延迟加载的实体,就无法关闭延迟加载。

  3. 自跟踪实体已被弃用,或者至少EF 团队建议不再在新项目中使用它们(第二个参考:http: //msdn.microsoft.com/en-us/data/jj613668)。他们还建议不再使用EntityObject派生实体。因此,POCO 绝对是要走的路。

    更改跟踪本身是 EF 的核心功能,也可用于两种不同形式的 POCO:作为“基于快照”的更改跟踪和更改跟踪代理。默认是基于快照的更改跟踪。更改跟踪代理可用于在某些情况下提高性能 - 特别是当涉及数千个实体并需要在单个上下文中更新时。有关更改跟踪代理的更多信息在这里:http ://blog.oneunicorn.com/2011/12/05/should-you-use-entity-framework-change-tracking-proxies/

  4. 如果启用延迟加载或动态更改跟踪,EF 会从 POCO 实体创建代理。它们是从您的实体类派生的动态对象,需要使延迟加载和动态更改跟踪(= 不基于快照)成为可能。

  5. 设置ProxyCreationEnabledfalse禁用任何代理创建 - 用于动态更改跟踪和延迟加载。如果代理创建关闭,则设置LazyLoadingEnabled不再重要。更多细节在这里:https ://stackoverflow.com/a/7112470/270591

  6. 如果您对数据库优先方法感到更自在,请使用它。它同样受到代码优先或模型优先的支持,并且 - 作为基于 EDMX 的方法 - 甚至具有代码优先所没有的一些更高级的功能。关于不同策略的更多细节在这里:https ://stackoverflow.com/a/5446587/270591

...尽管应用程序的 UI 层直接调用 BLL 中的方法,但将来我们可能希望将它们分开(例如通过 Web 服务)的可能性很小。这将如何影响设计考虑,以及我在上面提出的一些问题?

您将无法再在 UI 层中使用延迟加载,因为您无法通过 Web 服务边界传递上下文实例。延迟加载将变得毫无用处,就像在 UI 是(断开连接的)远程浏览器的 Web 应用程序中一样。您还将失去更改跟踪附加实体的舒适性。为断开连接的实体和对象图构建更改集比利用连接实体的更改跟踪更困难。所以,这个“小机会”很可能会对整个应用设计产生深远的影响。

于 2013-01-12T14:32:40.093 回答