开发者

Self Tracking Entities vs Pure POCO v. Future Proofing (3-tier)

开发者 https://www.devze.com 2023-03-20 22:50 出处:网络
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 i

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 th开发者_StackOverflowat 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?


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消