What Is the Purpose of Self Tracking Entities

What is the purpose of self tracking entities?

Self tracking entities (STE) are implementation of change set (previous .NET implementation of change set is DataSet). The difference between STE and other entity types (POCO, EntityObject) is that common entity types can track changes only when connected to living ObjectContext. Once common entity is detached it loose any change tracking ability. This is exactly what STE solves. STE is able to track changes even if you detach it from ObjectContext.

The common usage of STE is in disconnected scenarios like .NET to .NET communication over web services. First request to web service will create and return STE (entity is detached when serialized and ObjectContext lives only to serve single call). Client will make changes in STE and pass it back in another web service call. Service will be able to process changes because it will have STE internal change tracking available.

Handling this scenario without change tracking is possible but it is much more complex especially when you work with whole object graph instead of single entity - you must manually merge changes received from client to current state in database.

Be aware that STEs are not for interoperable solutions because their functionality is based on sharing STE code between server and client.

Self-Tracking Entities and POCO explanation needed

The IDE data designer, by default, creates an .edmx file which in earlier versions of Visual Studio (2008 and 2010) by default uses t4 templates that generate STE's by default and a context that derives from Object Context. In VS 2012, this was changed to generate POCO's by default with a context that derives from DbContext.

You can change this behavior by downloading a new code generator using NuGet.

Migrating from Self-Tracking Entities to DBContext

There is STE Generator template for EF 5.x and its information page says:

We no longer recommend using the STE template in new applications, it
continues to be available to support existing applications. Visit the
N-Tier Applications page for other options we recommend for N-Tier
scenarios.

That answers your question. If you want to use STEs without rewriting your application you should use the template and ObjectContext. In theory you can use DbContext because you can create a new instance of the DbContext from existing ObjectContext (through the constructor). I'm not sure what benefit it will have with STEs.

MS considers WCF Data Services and their client context as replacement for STEs.

Entity Framework Self-Tracking Entities not recommended by Microsoft

(NOTE: As I don't work for MS this is all conjecture based on their public statements and past history).

The first article you posted "sort of" explains the reason, though not very clearly: they want you to use a better alternative and have no intention of fixing or improving STEs. Microsoft is putting STEs into the bin of 'early failed experiments', similar to RDO or Remoting or LINQ2SQL -- they put something out to see how well it worked and it just didn't.

In general, it was always acknowledged by Microsoft that STEs were a first-stab at solving a real business problem but that they were clearly incomplete. In particular, they were really bad at attaching object graphs with shared entities, they didn't support lazy loading, and had a number of other miscellaneous limitations.

MS has apparently decided they're not going to try to clean them up (notice that they've also deprecated the POCO template, for similar reasons). Since they aren't planning to fix or improve the template, they want people to stop using it for new projects and move on to the better alternatives:

MSDN data library

DbContext Generator

This template will generate simple POCO entity classes and a context that derives from DbContext. This is the recommended template unless you have a reason to use one of the other templates listed below.

STEs existed mostly to support cases where entities were being disconnected and reconnected to their context, especially in serialization scenarios (WCF or web services, for example). In "standard" Entity Framework objects, all of the change tracking was done in the context, and attaching an existig entity to a context was problematic. STEs made that process easier, but at the cost of making almost everything else really hard.

From what I have seen and experienced about the DbContext it is supposed to be a better alternative to solve this problem, though it doesn't actually replicate what STEs did. The general consensus among heavy users of EF seems to be that serializing your EF entities end-to-end is a really bad idea. Instead you should be using DTOs and something like AutoMapper to map between your DTO and EF objects.

Self Tracking Entities vs POCO Entities

For me STE is absolutely wrong concept. It is just another implementation of DataSet.

  • In ASP.NET application you will have to store STEs somewhere among requests. In first request you will query your datasource to get STE and provide data in the page. In the next request (postback) you will want to modify STE with returned data from the browser. To support tracking you will have to use the same STE as in the first request => you will have to store STE in viewstate (if you want to use ASP.NET WebForms) or session.
  • STE is useless for SOA or interoperability. Tracking logic is part of STE = it is running on the client. If you expose STE in the service you are immediatelly expecting that client side will use the same tracking features included in STE logic. But these features are not provided to other side automatically. In .NET you have them because you share assembly with STEs. But on other platform you have to explain developers how to implement STE logic to make it work on your side. This will be probably the most limiting case for you because of iPhone application.

Self-tracking entities not recommended anymore. What is?

I think the idea is to move more generally to lighter weight pocos/dtos and keeping any an all persistence logic or implementation in your DAL. Self tracking entities sort of bleed some of that implementation out and fatten up your entities. You gain convenience, but loose flexibility as dumb dto's can be passed around easily with few suprises.

Of course the flip side to that is you need to do more work in your dal to track context and you need to do more work in your BLL and UI to deal with populating/mapping dto's.

I personally prefer flexibility over convenience and that seems to be the way things are going in general.

implement methods when i use Self-Tracking Entities

In Your WCF project you just need to reference your EntityClasses project. That simple?! I guess so...

Your Self-Tracking Entities are already equipped with the right DataMember attributes for the properties it carries.

Another thing...I see you use distinct methods for Add, Update and Delete. I always use a single Persist method that something goes like this:

using(Entities context = new Entities())
{
try
{
context.ApplyChanges(user);
context.SaveChanges();
}
catch
{
...
}
}

The Self-Tracking Entities context "knows" how to apply changes made to entities based on the ChangeTracker the STE is carrying. So you don't need seperate methods at all. Very easy to maintain.

So when you create a new entity in some client-application the ChangeTracker.State will be ObjectChangeTrackerState.Add and when modifying an existing entity it will be Modified and Deleted when you use entity.MarkAsDeleted().

Hope it helps.

How would I know if I should use Self-Tracking Entities or DTOs/POCOs?

If I understand your architecture, I think it is not good for STEs because:

  • Models are used on both the client-side and server-side for validation. We would not be binding directly to the DTO or STE

The main advantage (and the only advantage) or STEs is their tracking ability but the tracking ability works only if STE is used on both sides:

  • The client query server for data
  • The server query EF and receive set of STEs and returns them to the client
  • The client works with STEs, modifies them and sends them back to the server
  • The server receives STEs and applies transferred changes to EF => database

In short: There are no additional models on client or server side. To fully use STEs they must be:

  • Server side model (= no separate model)
  • Transferred data in WCF (= no DTOs)
  • Client side model (= no separate model, binding directly to STEs). Otherwise you will be duplicating tracking logic when handling change events on bounded objects and modifying STEs. (The client and the server share the assembly with STEs).

Any other scenario simply means that you don't take advantage of self tracking ability and you don't need them.

What about your other requirements?

  • Users can define their own interface, so the data needed from the WCF service changes based on what interface the user has defined for them.

This should be probably possible but make sure that each "lazy loaded" part is separate structure - do not build complex model on the client side. I've already seen questions where people had to send whole entity graph back for updates which is not what you always want. Because of that I think you should not connect loaded parts into single entity graph.

  • There are permission checks on the server-side which affect how the data is returned. For example, some data is either partially or fully masked based on the user's role

I'm not sure how do you want actually achieve this. STEs don't use projections so you must null fields directly in entities. Be aware that you must do this when entity is not in tracking state or your masking will be saved to the database.

  • The Database layer spams multiple servers/databases

It is something that is not problem of STEs. The server must use a correct EF context to load and save data.

STEs are implementation of change set pattern. If you want to use them you should follow their rules to take full advantage of the pattern. They can save some time if used correctly but this speed up comes with sacrifice of some architectural decisions. As any other technology they are not perfect and sometimes you can find them hard to use (just follow self-tracking-entities tag to see questions). They also have some serious disadvantages but in .NET WPF client you will not meet them.

NHibernate and self tracking entities

I don't really know what "self-tracking entities" means, I guess it comes from entity framework? The IStatelessSession does not cache entities. The session is not build to have a lot of entities in the cache, but to only contain the entities to show on the screen to the user. If you need batching, or long running transactions, other tools will do the job better than NHiberante. I guess it is not build in NHiberante for the following reasons:

  • People already use other tools.
  • There is not much existing code and there are not much existing features to build it.
  • Existing features need breaking changes or have to be sacrificed.
  • Somebody has to write the code...


Related Topics



Leave a reply



Submit