I've been reading about self-tracking entities in .net and how they can be generated from a *.edmx file. The thing that I'm struggling to understand is what generating these entities gives you over the basic EF entities? Also, some people have mentioned self tracking entities and Silverlight, but why would you use these rather than the client side or shared classes generated by RIA services?
What is the point of self-tracking entities and why would you use them?
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.
The main purpose is to aid in N-tier development. Since they're self-tracking, you can serialize them over, say, a WCF service, then de-serialize them back, and they will still know which changes have been made, and are pending for the database.
Self-tracking entities know how to do
their own change tracking regardless
of which tier those changes are made
on. As an architecture, self-tracking
entities falls between DTOs and
DataSets and includes some of the
benefits of each.
http://blogs.msdn.com/b/efdesign/archive/2009/03/24/self-tracking-entities-in-the-entity-framework.aspx
Related
I'm familiar with the EF and it looks pretty cool. As far as I can see, it is basically a LINQ to SQL with extra functions (like caching, automatic connection handling and so on). However, in my opinion EF is useful for those applications that directly comminicate with the model data (~persistence).
In case of writing a RESTful web service, we are reading and writing objects (for example) in JSON format. The application calls the web service with some data and it returns data back.
That's why I'm actually thinking on not using EF because it looks like an overkill for me. Since I'm not planning to expose the actual model, I would use DTOs instead (both as input and output of a web service call). This means that I have to do the mapping to the underlying model anyway so the EF would be used as a LINQ to SQL wrapper.
Is there anything I'm missing? Is there any feature that would be useful while writing a RESTful web service? is there any benefit from using EF instead of LINQ to SQL?
So the logic here is that you aren't exposing your entities past the data layer, so EF is pointless.
I never expose my EF Entities pass the business layer, just one layer down from the data layer. I always project them to ViewModels and Models which are just POCOs. I've seen this in lots of projects.
Rarely do I actually use the entity change tracking features. By the time a GET/POST has occurred it doesn't make sense to requery the entities on the POST just so you can update them via change tracking. Instead a direct update makes more sense and avoids an unnecessary roundtrip to the database.
My point being is in what I've seen it most commonly used, the EF models are not exposed past more than one layer in most cases. This ensures View/UI layers don't accidentally modify EF state or cause lazy loading(which is usually disabled).
However I still get to leverage the great EF/DB mapping layer and EF LINQ queries, which is by far the greatest features of EF.
Most alternatives such as Dapper are just that, a framework for executing queries.
So I wouldn't fallback to just doing ADO.NET or an older query technology just because you aren't using all the features of EF. You should still use a modern query framework such as EF or Dapper, simply because you are still executing queries. Just because you aren't exposing the entities doesn't change that.
I have following layers in my applicaiton
Date Layer (reference to Model)
Business Layer(reference to Model ,Data)
Model
Service(WCF)-(reference to Model,Business Layer)
UI (WPF/Silver Light) - Connected via WCF service
How do i detect the changed poco entities in an ObservableCollection in UI layer?
for sending it back to server from client side for saving ? instead of sending all data back to sever side(via WCF)?
or
how to perform add/delete/update operation on entities in the collection in UI layer?
I am using
VS2010/2012
C#
EF 5
ADO.NET POCOEntityGenerator With WCF Support(for generating .tt templates from Model.edmx)
SQL Server 2012
Even though searched a lot of places I didn't find a proper solution..
please help if any ideas...
Thanks...
The method i followed to create My application is given below link
http://www.toplinestrategies.com/dotneters/net/wcf-entity-framework-and-n-tier-solutions-part-2/?lang=en/comment-page-1/#comment-1954
Only proper solution is to do the change tracking manually. Each POCO object will have IsDirty property and each property of this object will have IsDirty = true in it's setter.
One way to make it less manual would be to create a framework, that will create wrapper classes, that will do this for you, but this requires large dose of reflection and code-generation. Also, it will still require all properties to be defined as virtual.
But generally, you want to refrain from making UI that would require this kind of tracking. When you want to change an entity, load only that entity in Edit window.
POCOs are well-suited for transmitting data between client and server. However, if you’re looking for objects to actually work with on client and/or server side you may want to consider using self-tracking entities (STE) as these entities contain logic to track their actual changes and status.
Yet a better solution is to use the N-Tier Entity Framework which provides functionality to work with EF in n-tier applications. See http://ntieref.codeplex.com/ for more details.
If you are using EF, then your entities have a 'HasChanges' flag you can test against before submitting changes to your context.
e.g.
if (this.CurrentEntity.HasChanges || CurrentEntity.EntityState == EntityState.New)
{
this.SubjectContext.SubmitChanges(Submit_Completed, saveDetails);
}
We are using .net C# 4.0, VS 2010, EF 4.1 and legacy code in this project we are working on.
I'm working on a win form project where I have made a decision to start using entity framework 4.1 for accessing an ms sql db. The code base is quite old and we have an existing data layer that uses data adapters. These data adapters are used all over the place (in web apps and win form apps) My plan is to replace the old db access code with EF over time and get rid for the tight coupling between UI layers and data layer.
So my idea is to more or less combine EF with the legacy data access layer and slowly replace the legacy data layer with a more modern take on things using EF. So for now we need to use both EF and the legacy db access code.
What I have done so far is to add a project containing the edmx file and context. The edmx is generated using database first approach. I have also added another project that contains the POCO classes (by using ADO.NET POCO Entity Generator). I have more or less followed Julia Lerman's approach in her book "Programming Entity Framework" on how to split the model and the generated POCO classes. The database model has been set for years and it's not an option the change the table and the relationships, triggers, stored procedures, etc, so I'm basically stuck with the db model as it is.
I have read about the repository pattern and unit of work and I kind of like the patterns, but I struggle to implement them when I have both EF and the legacy db access code to deal with. Specially when I don't have the time to replace all of the legacy db access code with a pure EF implementation. In an perfect world I would start all over again with a fresh take one the data model, but that is not an option here.
Is the repository and unit of work patterns the way to go here? In order to use the POCO classes in my business layer, I sometimes need to use both EF and the legacy db code to populate my POCO classes. In another words, I can sometimes use EF to retrieve a part of the data I need and the use the old db access layer to retrieve the rest of the data and then map the data to my POCO classes. When I want to update some data I need to pick data from the POCO classes and use the legacy data access code to store the data in the database. So I need to map the data retrieved from the legacy data access layer to my POCO classes when I want to display the data in the UI and vice versa when I want to save data to the data base.
To complicate things we store some data in tables that we don't know the name of before runtime (Please don't ask me why:-) ). So in the old db access layer, we had to create sql statements on the fly where we inserted the table and column names based on information from other tables.
I also find that the relationships between the POCO classes are somewhat too data base centric. In another words, I feel that I need to have a more simplified domain model to work with. Perhaps I should create a domain model that fits the bill and then use the POCO classes as "DAO's" to populate the domain model classes?
How would you implement this using the Repository pattern and Unit of Work pattern? (if that is the way to go)
Alarm bells are ringing for me! We tried to do something similar a while ago (only with nHibernate not EF4). We had several problems running ADO.NET along side an ORM - database concurrency being a big one.
The database model has been set for
years and it's not an option the
change the table and the
relationships, triggers, stored
procedures, etc, so I'm basically
stuck with the db model as it is.
Yep. Same thing! The problem was that our stored procs contained a lot of business logic and weren't simple CRUD procs so keeping the ORM updated with the various updates performed by a stored procedure was not easy at all - Single Responsibility Principle - not a good one to break!
My plan is to replace the old db
access code with EF over time and get
rid for the tight coupling
between UI layers and data layer.
Maybe you could decouple without the need for an ORM - how about putting a service/facade layer infront of your UI layer to coordinate all interactions with the underlying domain and hide it from the UI.
If your database is 'king' and your app is highly data driven I think you will always be fighting an uphill battle implementing the patterns you mention.
Embrace ado.net for this project - use EF4 and DDD patterns on your next green field proj :)
EDMX + POCO class generator results in EFv4 code, not EFv4.1 code but you don't have to bother with these details. EFv4.1 offers just different API which does exactly the same (and it is only wrapper around EFv4 API).
Depending on the way how you use datasets you can reach some very hard problems. Datasets are representation of the change set pattern. They know what changes were done to data and they are able to store just these changes. EF entities know this only if they are attached to the context which loaded them from the database. Once you work with detached entities you must make a big effort to tell EF what has changed - especially when modifying relations (detached entities are common scenario in web applications and web services). For those purposes EF offers another template called Self-tracking entities but they have another problems and limitations (for example missing lazy loading, you cannot apply changes when entity with the same key is attached to the context, etc.).
EF also doesn't support several features used in datasets - for example unique keys and batch updates. It's fun that newer MS APIs usually solve some pains of previous APIs but in the same time provide much less features then previous APIs which introduces new pains.
Another problem can be with performance - EF is slower then direct data access with datasets and have higher memory consumption (and yes there are some memory leaks reported).
You can forget about using EF for accessing tables which you don't know at design time. EF doesn't allow any dynamic behavior. Table names and the type of database server are fixed in mapping. Another problems can be with the way how you use triggers - ORM tools don't like triggers and EF has limited features when working with database computed values (possibility to fill value in the database or in the application is disjunctive).
The way of filling POCOs from EF + Datasets sounds like this will not be possible when using only EF. EF has some allowed mapping patterns but possibilities to map several tables to single POCO class are extremely limited and constrained (if you want to have these tables editable). If you mean just loading one entity from EF and another entity from data adapter and just make reference between them you should be OK - in this scenario repository sounds like reasonable pattern because the purpose of the repository is exactly this: load or persist data. Unit of work can be also usable because you will most probably want to reuse single database connection between EF and data adapters to avoid distributed transaction during saving changes. UoW will be the place responsible for handling this connection.
EF mapping is related to database design - you can introduce some object oriented modifications but still EF is closely dependent on the database. If you want to use some advanced domain model you will probably need separate domain classes filled from EF and datasets. Again it will be responsibility of repository to hide these details.
From how much we have implemented, I have learned following things.
POCO and Self Tracking objects are difficult to deal with, as if you do not have easy understanding of what goes inside, there will be number of unexpected behavior which may have worked well in your previous project.
Changing pattern is not easy, so far we have been managing simple CRUD without unit of work and identity map pattern. Now lot of legacy code that we wrote in past does not consider these new patterns and the logic will not work correctly.
In our previous code, we were simply using transactions and single insert/update/delete statement that was directly sent to database assuming transactions on server side will take care of all operations.
In such conditions, we were directly dealing with IDs all the time, newly generated IDs were immediately available after single insert statement, however this is not case with EF.
In EF, we are not dealing with IDs, we are dealing with navigation properties, which is a huge change from earlier ADO.NET programming methods.
From our experience we found that only replacing EF with earlier data access code will result in chaos. But EF + RIA Services offer you a completely new solution where you will probably get everything you need and your UI will very easily bind to it. So if you are thinking about complete rewriting using UI + RIA Services + EF, then it is worth, because lot of dependency in query management reduces automatically. You will be focusing only on business logic, but this is a big decision and the amount of man hours required in complete rewriting or just replacing EF is almost same.
So we went UI + RIA Services + EF way, and we started replacing one one module. Mostly EF will easily co-exist with your existing infrastructure so there is no harm.
I have a setup with Client -> WCF -> POCO -> EF4.
Say I have a list with A entities. The A entity contain among other properties a huge list of B entities that isn't loaded by default. When a certain action is done on the client, it may need to know the list of B entities...
If I load the B entities for the A entity and attach them to the collection, the A entity is in effect changed, and I guess when saving the entity it will also save these 'new' B entities to the A entity?
I could wire up a GetEntityWithAllDetails function, but then I would get some data that I already have, and if there were other collections I didn't want to load, it would be a complete mess.
The question can be boiled down to how can I recomplete the POCO on the client side when I only have a partial POCO to start with and want to avoid loading data twice and still being able to rely on EF4 to save the entity correctly?
That is a complex task and EF doesn't handle it - it is your responsibility. When you use detached entities the change tracking is up to you.
Your solution currently probably is:
Client sends request to WCF service
WCF uses EF to get data, close context and return POCO graph or partial graph back to client
Client modifies the POCO graph / partial graph and sends modified data back to WCF service
WCF creates new EF context and saves the POCO graph
Sounds easy but it doesn't. In the last step you must manually explain to the new context what has changed. It generally means heavy interaction with ObjectStateManager (in case of ObjectContext API) or DbChangeTracker (in case of DbContext API). It also means that you must pass information about changes from the client.
For example suppose that you are modifing Order entity. Order entity is dependent on Customer entity and it has dependent OrderItem entities. To make this interesting suppose that OrderItems must be processed by different warehouses so each warehouse has access only items assigned to it.
In the step one you will request Order from one warehouse
In the step two you will retireve Order without Customer and with a supset of OrderItems.
In the step three the warehouse modifies sevaral OrderItems as processed. Deletes single OrderItem because of discontinued product and inserts another OrderItem for replacement of discontinued product. Because of insufficient supplies some items will be unchanged. The warehouse sends Order back to the server.
What will you do in the step four? You must apply some knowledge. The first knowledge is that cutomer was not send to client so you can't modify a customer relation. In case of foreign key relation it means that CustomerId can't be modified. Now you must explicitly say which OrderItem was updated (= exists in DB), which was unchanged (= doesn't need any action), which was inserted (= must be inserted) and the worst part which was deleted (if you don't send some information about deletion from the client you can't know it without reloding the entity graph from the database).
At least you can be happy that EF will not delete anything you explicitly don't mark for deletion. So order items related to other warehouses and their relations to the order will be unchanged.
There are two general approaches how to deal with it:
Load entity graph first and merge changes into the graph. Then save the attached (loaded) graph. You will simply compare the loaded entity graph with the received entity graph and process all required updates, deletes, inserts.
Use self tracking entities instead of POCOs which are implementations of Change set pattern and are able to track changes on the client. STEs have some disadvantages which make them useless in certain scenarios.
There is also completely separate architecture approach using DTOs instead of direct EF POCOs but it results in same complications as you have at the moment.
Welcome to n-tier development.
This sort of situation is exactly why many architected enterprise scale solutions use data transfer objects between tiers.
I would recommend avoiding domain entity propagation from the service (business) tier to the client. If you go down the track of having entities become aware of whether they are fully loaded, or what tier they are currently on, they are hardly "POCO" are they?
So you write a service method "GetEntityWithAllDetails". It should take a GetEntityWithAllDetailsRequest object and return a GetEntityWithAllDetailsResponse object containing whatever the caller of the service expects, and no more.
Obviously there is a far bit of mapping to be done between between DTO's and domain objects - libraries such as Automapper (and others) can help with that.
Propagating domain entities to the client also retricts your flexibiltiy with regards to lazy or eager loading of entities and leaves you having to deal with re-attaching/merging entities, which is problem with EF becuase it will not re-attach entity graphs - you must walk the graph manually.
I will try and say it really plainly. Propagating domain entities from the service to the client is the road to programming hell and very quickly leads to objects having all sorts of responsibilties that are orthoganol to their purpose.
I have POCO's in a separate project and now I need Self Tracking Entities. Does anyone know if I need to generate new POCO's that are self tracking and they will replace my current POCO's? Or, do I setup self tracking entities in addition to my current POCO's?
Thanks!
You do not need both. STE is essentially POCO with additional capability for change tracking when disconnected from the ObjectContext. I would suggest that you stick with STE if you have n-tier scenario. For non N-Tier scenario meaning when you are working with your entities on the server side, you can use it like a poco object and let ObjectContext manage change tracking for you.