【问题标题】:Self Tracking Entities vs Pure POCO v. Future Proofing (3-tier)自我跟踪实体与纯 POCO 与未来证明(3 层)
【发布时间】:2011-10-07 22:17:06
【问题描述】:

这显然是一个已经讨论过很多次的话题,但是我在这里的处理角度有点不同。据我了解,STE 被认为是 POCO(它不以任何方式与 EF dll 绑定),它只是在其中包含一些额外的“东西”,用于处理自己的更改跟踪。假设有以下应用层:

Proj.Web
Proj.Business
Proj.Model
Proj.DataAccess

假设 lazy loading 不是必需的,并且我们在 2 层设置中运行,我的理解是使用 STE 和 POCO 之间确实没有区别。由于我们在 Web 上并且它是一个断开连接的环境,因此选择将是对 Postback 的附加 SQL 查询,或者必须附加实体并将属性设置为根据需要进行修改。再次(如果我错了,请纠正我)代码看起来相同。

让我们考虑一个简单的例子,我们正在处理 webform 应用程序中的回发:

Person p = PersonManager.GetById(2); //we use the "requery" method
PersonManager.Update(p);

//If we dig into PersonManager.Update() we'll see the following:
PersonRepository.ApplyChanges(p); //we're assuming STEs are used so this API is available
PersonRepository.SaveChanges();

假设稍后我们被要求将架构提升到 3 层,在 Proj.Bussiness 和 Proj.Web 之间引入 WCF 传输层,我们称之为 Proj.Services。如果我们一开始就使用 STE,我们不是处于一个更好的位置吗?我们所要做的就是将调用转发到业务层,而无需以任何方式修改它或存储库:

PersonService.Update(Person p)
{
    PersonManager.Update(p);
}

例如,如果我们使用 POCO(让我们假设快照),我们必须以一种必须检查该实体是否已经存在于上下文中的方式进行编码(如果我们正在运行 2 层)以及是否不是(3 层)附加它并将其属性设置为已修改。当您不确定将来是否需要 3 层解决方案时,似乎需要做更多的工作。另一方面,如果您一直都在针对 STE 进行编码,那么您将添加的唯一额外不必要的(实际上并没有损害任何东西)代码是对 ApplyChanges() 的调用。否则,我认为您不会丢失任何东西(再次假设不需要延迟加载)。你对这个话题有什么看法?

【问题讨论】:

  • 可能是洋葱架构?是的,你真的不需要规划 3 层架构,但对我来说感觉更自然。不是 3 层应用程序 Ui 层,业务逻辑 - 任何人都可以更新数据吗?权限?多米安模型?那么你有数据访问的持久性......或者我的理解很好,请纠正我......
  • @Haroon,你所说的3层实际上是3层(逻辑),但可以在2层(物理)中运行。我不确定我是否了解您的其他问题。
  • @e36M3 - 可悲的是,“Tier”这个词在当今的行业中已经失去了所有意义,试图收回它的真正目的是没有希望的。出于所有意图和目的,如今一个层就是一个层。
  • @Mystere Man:只是因为有太多的开发人员不了解其中的区别。即使在现在,区分层和层 - 逻辑和物理边界也非常重要。
  • @Ladislav Mrnka - 不仅仅是开发人员.. 书籍甚至会犯这个错误。我试图与其他开发人员和经理争论这一点,他们就是不明白。几乎没有人知道真实的事情,所以这是一个徒劳的立场。接受它并打一场你能赢得的战斗。这就像试图说服人们在数据库中使用自然键而不是在所有内容上猛击身份列。

标签: .net asp.net entity-framework entity-framework-4 self-tracking-entities


【解决方案1】:

Ladislav Mknka 就为什么不使用 STE 提出了一些很好的观点,但是对于这个问题似乎真的没有一个万能的答案。例如,在我当前的 2 层项目中,它们可能是不必要的。但是,我们强烈希望在未来将 Silverlight 用于该项目的管理部分。这意味着我有一个用于模型和存储库的项目,希望能在两个更高层项目中使用。所以一个运行 2 层,另一个运行 3 层(因为 Silverlight 需要服务)。据我所知,STE 的行为就像“连接”环境中的快照 POCO 一样,因此在 2 层应用程序中使用它们不会损失/获得太多。然而,当我们添加 3 层 Silverlight 部件时,它们可能会非常有用。希望我在原始帖子中描述的方法将证明对这两种类型的应用程序都有效。

显然还有其他方法可以解决这个问题,人们总是可以以一种方式编写他们的存储库,这样他们可以确定是否正在跟踪特定实体并根据该决定执行必要的任务,我倾向于认为这样下去就开发工作而言,路径将被证明成本更高。我想只有时间会证明一切。

【讨论】:

    【解决方案2】:

    STE 不太适合 Web 应用程序。他们的问题是他们的工作方式:

    • 您加载 STE 并关闭上下文
    • 使用 STE 中提供的数据
    • 将数据推送回 STE
    • 您将 STE 中的更改应用到新的上下文中,它只是传递对象图中的所有更改

    这似乎是一个很棒的功能,但也许不是。对于 ASP.NET,它通常意味着:

    • 为初始检索请求加载数据并将 STE 存储在某处
    • 在以下更新请求中取回数据并将数据填充回存储的 STE

    这很糟糕,因为它要求您将 STE 存储在会话或视图状态中。

    您描述的方法将以另一种方式起作用。您不会存储初始请求中的 STE,但您将在更新请求中调用您的服务两次

    • 第一次拿到新的STE
    • 第二次传回更新后的 STE

    这并没有好多少,因为您有额外的远程调用,可以传输大量数据(对象图),然后将整个对象图传回。

    显然这两种方法都违反了一些架构思想

    • 不要在 Web 应用程序中存储不必要的状态,因为 Web 应用程序应该尽可能少的状态
    • 将远程调用减少到最低限度,因为它们非常昂贵 + 将传输的数据量减少到您真正必须传递的数据

    他们可以使远程场景更容易,但他们有自己的成本(和they are .NET-.NET solution)。如果您没有远程场景 = If you don't have to use STEs simply don't do that,则没有使用它们的单一理由。此外,有报道称其实施存在一些问题。在用户语音中,您甚至可以找到they don't work at all 的建议。

    【讨论】:

    • 所有非常好的观点。我假设额外的查询/远程调用是“好的”,我认为在这个假设下我的理论是正确的。但是,如果我们想远离额外的查询和 STE。对于编写易于从 2 层解决方案更新为 3 层解决方案的代码,您有什么建议?你会像我在上一段关于条件附加的描述中那样做吗?
    • 我个人的看法是——不要为目前不需要的东西创建架构,因为“将来可能需要它”毫无意义。一旦你对应用程序的所有细节有真正的需求,你应该重新设计/重构应用程序。
    • 我明白你的意思。我问的真正原因是因为在未来我预见到必须使用 silverlight 针对同一个 EDMX 构建一个内部部件,因此可能会发生断开连接的情况。我希望能够分享我现有的模型和业务逻辑。我在想,如果我从 STE 开始,那么没有什么坏处,但是当我必须引入 WCF 时,它会真正得到回报。
    • @LadislavMrnka 一如既往的好答案。在大量使用 POCO 并在 SO 上阅读了许多与此类似的问题的答案(其中许多是您的答案)之后,我仍然不明白... STE 有什么好处?在什么情况下您需要它们?他们打算做什么以及什么时候错(或正确?)嗯,也许我应该为此添加一个问题。
    • @DannyVarod:This answer 描述了 STE 应该解决的问题。新方法是使用 WCF 数据服务进行客户端更改跟踪,而不是在每个实体内传递所有跟踪信息。
    猜你喜欢
    • 2011-08-24
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 2011-01-21
    • 1970-01-01
    • 1970-01-01
    • 2011-08-22
    • 1970-01-01
    相关资源
    最近更新 更多