自跟踪实体 vs 纯 POCO vs. 面向未来(3 层)

发布于 2024-11-25 01:17:57 字数 1194 浏览 2 评论 0原文

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

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

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

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

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() 的调用。否则我认为你不会丢失任何东西(再次假设不需要延迟加载)。您对此主题有何看法?

This is obviously a topic that has been discussed many times, however my angle of approach here is a little different. As far as I understand, a STE is considered a POCO (it is not tied to the EF dll in any way), it just has some extra "stuff" inside of it for handling its own change tracking. Assuming the following application layers:

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

Assuming lazy loading is not required, and we're running in a 2-tier setup, my understanding is that there would really be no difference between using STEs and POCOs. Since we're on the web and it's a disconnected environment, the choices would be an additional SQL query on the Postback or having to attach the entity and set the properties to modified as necessary. Again (correct me if I'm wrong) the code would look identical.

Lets consider a simple example, we're handling a postback in a webform application:

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();

Assuming later down the line we are asked to promote the architecture to a 3-tier, introducing a WCF transport layer in between the Proj.Bussiness and Proj.Web, lets call it Proj.Services. If we were using STEs to begin with, aren't we in a much better spot? All we'd have to do is forward the calls to the business layer, without having to modify it or the repositories in any way:

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

If for example we were using POCOs (lets assume snapshot), we'd have to code in a way where we have to check if this entity already exists in the context (if we're running 2-tier) and if not (3-tier) attach it and set it's properties to modified. Seems like a lot more work when you're not sure if a 3-tier solution would be needed in the future. On the other hand if you were coding against STEs all along, the only extra unnecessary (which doesn't really harm anything) code you would have put in is a call to ApplyChanges(). Otherwise I don't think you're losing anything (again assuming lazy loading is not required). What are your thoughts on the subject?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

妖妓 2024-12-02 01:17:58

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

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

Ladislav Mknka made some excellent points on why NOT to use STEs, however it seems there really isn't a one size fits all answer to this question. For example in my current 2-tier project, they might be unnecessary. However we're strongly looking at utilizing Silverlight for an administration piece of this project in the future. This will mean that I have one project for the model and repositories, that hopefully will be utilized across both higher layer projects. So one running 2-tier and another running 3-tier (since Silverlight requires services). As far as I can tell STEs behave just like snapshot POCOs in a "connected" environment, so I don't lose/gain much by using them as such in a 2-tier app. However they'll likely prove to be very useful when we add the 3-tier Silverlight piece. Hopefully the method described in my original post will prove to work well for both types of applications.

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.

亢潮 2024-12-02 01:17:57

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

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

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

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

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

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

  • 第一次获取新的 STE
  • 第二次将更新后的 STE 传回

这也好不了多少,因为您有额外的远程调用,可以传输很多内容数据(对象图),然后将整个对象图传回。

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

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

它们可以使远程场景变得更加容易,但它们有自己的成本(并且它们是.NET-.NET解决方案)。如果您没有远程场景 = 如果您不必使用 STE,就不要这样做。此外,有报告称其实施存在一些问题。在用户声音中,您甚至可以找到它们根本不起作用

STEs are not very well suited for web application. Their problem is how they work:

  • You load STE and close the context
  • Work with data provided in STE
  • Push data back to STE
  • You apply changes from STE to a new context and it simply pass all changes in object graph

That seems like great feature but perhaps it is not. In case of ASP.NET it most often means:

  • Load data for initial retrieval request and store STE somewhere
  • Get data back in following update request and fill data back to stored STE

That is awful because it requires you to store STE either in session or view state.

The approach you described will work in another way. You will not store STE from initial request but you will call your service twice in your updating request

  • First time to get a new STE
  • Second time to pass the updated STE back

That is not much better because you have additional remote call which can transfer a lot of data (object graph) and after that pass whole object graph back.

Obviously both approaches violates some architectonic ideas

  • Don't store unnecessary state in web application because web application should be state less as possible
  • Reduce remote calls to minimum because they are very costly + reduce amount of transferred data to data you really have to pass

They can make remote scenarios much more easier but they have their own costs (and they are .NET-.NET solution). There is no single reason to use them if you don't have remote scenario = If you don't have to use STEs simply don't do that. Moreover there are reports with some problems with their implementation. At user voice you can even find suggestion that they don't work at all.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文