0

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

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

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

让我们考虑一个简单的例子,我们正在处理 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 -tier) 附加它并将其属性设置为已修改。当您不确定将来是否需要 3 层解决方案时,似乎需要做更多的工作。另一方面,如果您一直都在针对 STE 进行编码,那么您唯一需要添加的额外不必要的(实际上并没有损害任何东西)代码就是调用 ApplyChanges()。否则,我认为您不会丢失任何东西(再次假设不需要延迟加载)。你对这个话题有什么看法?

4

2 回答 2

2

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

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

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

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

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

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

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

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

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

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

它们可以使远程场景更容易,但它们有自己的成本(而且它们是 .NET-.NET 解决方案)。如果您没有远程场景,则没有使用它们的单一理由 =如果您不必使用 STE,请不要这样做。此外,有报道称其实施存在一些问题。在用户语音中,您甚至可以找到他们根本不起作用的建议。

于 2011-07-18T21:15:35.730 回答
0

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

There are obviously other ways to solve this problem, one could always write their repositories in a way where they determine if a specific entity is being tracked and perform the necessary tasks based on that decision, I tend to think that going down that path would prove to be much more costly in terms of development effort. I suppose only time will tell.

于 2011-08-07T19:55:52.933 回答