IDisposable entities in Entity Framework Code First - entity-framework

My business logic and core entities are tightly coupled.
An object, for example, called Session is a database entity but in literal terms of the word is a real life Session during which events are recorded.
This Session object also has [NotMapped] objects and handles to unmanaged resources.
The Session object also implements IDisposable.
A good chunk of entities in my project have the above characteristics.
This sounds like disaster down the line. The question is what approach to take here.
I am expecting answers to point to design patterns or architecture but please do include a very short code example to illustrate your point rather than just the name of the proposed solution.
What I have thought of so far is to derive from each entity as a business object and use code generation to convert from one type to the other. Since this is a client/server application, I want to be able to use the entity relationship set as-is in my desktop app, albeit a derived one.
Not sure how to achieve this in a sustainable way.

This is not about design patter but about ownership of the disposable entities. Who owns the entity? The owner is responsible for disposal. That is something defined directly by your code / design.
EF context itself is disposable - you can override its Dispose operation and force it to dispose all attached entities but that is most probably something you don't want to do because context is most probably not the owner of the entity. The code requesting entities from context or requesting persistence of entities should be considered as owner responsible for disposal.

Related

A static DbContext object for read-only purposes in ASP.NET MVC WebAPI

I'm refactoring my ASP.NET MVC 4 WebAPI project for performance optimization reasons.
Within my controller code, I'm searching for entities in a context (DbContext, EF6). There are a few thousands of such entities, new ones are added on an hourly basis (i.e. "slowly"), they are rarely deleted (and I don't care if deleted entities are still found on the context's cache!) and are never modified.
After reading the answers to this question, to this one and a few more discussions, I'm still not sure it's a bad idea to use a single static DbContext for the purpose described above - a DbContext which never updates the database.
Performance-wise, I'm not worried about the instantiation cost, but rather about the uselessness of caching requested entities if the DbContext is created for each request. I'm also using a 2nd level caching, which makes the persistence of the context even more acute.
My questions are:
1. Regardless of the specific implementation, is a "static" DbContext a valid solution in my case?
2. If so, what would be the most appropriate way of implementing such a DbContext?
3. Should I periodically "flush" the context to clear the cache in order to prevent if from growing too big?
DbContext caches entity instances when you get/query the data. It ensures different queries that return the same data map to the same entity (based on type and id). Otherwise, if you modify the same entity in different object instances, the context would not know which one has the correct data. Therefore a static DbContext would blow up over time until the process crashes.
DbContexts should be short lived. Request.Properties is a good place to save it in Web API (maps to HttpContext.Items in IIS).

What problems can arise from storing a DbContext reference in a POCO object?

I am new to a 15 year old application. The team lead has started using Entity Framework + alongside existing WebForms + Sprocs.
Some POCOs (domain entities) in EF have properties containing references to the DbContext, usually parent objects at the top of an object graph. As I attempt to write tests, I continually get Context Disposed exceptions.
public EmployerService(int UserID, Entities entities) // business layer
{
this.UserID = UserID;
_entities = entities;
}
internal Employer CreateEmployer()
{
Employer employer = _entities.Employers.Create();
employer.MasterItem = _entities.MasterItems.Create();
employer.MasterItem.LastModified = _entities.ItemLastModifieds.Create();
employer.DBContext = _entities;
...
return employer;
}
More to the point, the project references are not clean. The POCOs reference Data and Business logic layers. I am building a case to get the DbContext references out of the POCO objects, but my search is just beginning.
So my question is, what design principles support or reject referencing the DAL layer from the POCOs?
Your DAL layer sneaks into Business Logic layer. Service now tightly coupled to Entity Framework (BTW I don't think it's good idea to add reference to EntityFramework.dll into your domain project). Consider we are moving to NHibernate. What you should change? Everybody would think it's a DAL task. But wait guys, I have some DAL in my domain! We should change EmployerService class.
So, keep your domain entities persistent ignorant. Especially keep them ignorant of concrete persistence technology you are using. And I think better place for Employer creation is a factory. Also I don't understand why you are not using simple constructors here? Looks like you can avoid Entity Framework usage during Employer creation.
The most vocal design principle here is that you're having problems with the current design.
DbContext is supposed to be used as a short-living - and it's not meant to be stored for later. The reference you're holding doesn't mean much, as it gets Disposed.
To the very least you should check if it's Disposed (you can do that by overriding Dispose I guess, setting a flag or something). But what to do if it is?
Basically, if you still do use it that way - make sure your POCO objects are `short-lived' as well - but that gets painful I'm sure.

Entity Framework Caching

I'am reading a article about the differences between Nhibernate and EF.
But i could not understand what they wanted to say with caching on a field.
As for Entity Framework, the ObjectContext/DbContext holds the configuration, model and acts as the Unit of Work, holding references to all of the known entity instances. This class is therefore not lightweight as its NHibernate counterpart and it is not uncommon to see examples where an instance is cached on a field.
I did not create a link to article, because i was not 100% sure it was allowed.
Note the wording carefully; they are speaking of the DbContext itself, and comment that it is not uncommon to see examples where "the instance" (the DbContext) is cached on a field.
What they mean is, rather than creating and destroying a DbContext object with a local scope in a method, you'll see people save the DbContext instance to a field of a broader object and reuse it.

How entity framework track the loaded entities? what are their life cycle?

I am relatively new to entity framework, all the documents or books I can find are talking about how to use the framework, or which model should be used, but short of explanation how the framework works in depth.
For instance, when I load the entities from the database via either LINQ query or framework methods, are those entities thread safe? In another words can they be shared with other threads? If so how EF controls the consistency?
When control goes out of context, are those entities gone or still in memory? After .SaveChanges are those entities gone? What is the life cycle?
Can an expert in EF explain the above points in details please.
Thanks in advance.
The life cycle of loaded entities is more-or-less tied to that of the Entity Context which loaded them. Hence in many examples you will see:
using (var ctx = new Context())
{
// ... do work
} // The context gets disposed here.
Once the context is disposed (at the end of the using statement, e.g.), you should no longer treat entities that were loaded inside the context as if you can load additional information from them. For example, don't try accessing navigation properties on them. To avoid problems, I usually find it best to create a DTO that has only the exact data that I expect people to be able to use, and have that be the only value that leaves the using statement.
using (var ctx = new Context())
{
var q = from p in ctx.People
select new PersonSummary{Name = p.Name, Email = p.Email};
return q.ToList(); // This will fully evaluate the query,
// leaving you with plain PersonSummary objects.
}
Entity Contexts are not thread-safe, so you shouldn't be trying to load navigation properties and such from multiple threads for objects tied to the same context, even within the context's lifecycle.
For instance, when I load the entities from the database via either LINQ query or framework methods, are those entities thread safe? In
another words can they be shared with other threads? If so how EF
controls the consistency?
The ObjectContext class is not tread safe. You must have one object context per thread or to create you own thread synchronization process. This way the consistency is managed by the ObjectContext since it tracks all the objects' state.
When control goes out of context, are those entities gone or still in memory? After .SaveChanges are those entities gone? What is the life
cycle?
ObjectContext class inherit from IDisposable interface so you can, and should, use USING statement when using Entity Framework. This way they're gone after you close the using statement. If you DO NOT dispose the context they keep being tracked, only their states are changed. Disposing ObjectContext instances will also make sure that the database connection is properly disposed and you are not leaking database connections.
So, the big question is:
Where and when should EF live?
Theses ORM should be treated as the Unit of Work pattern, that is, the ORM object should live until the business task is done.
In my specific scenarios I use an IoC container like Windsor that does the heavy lifting for me. In an ASP.NET MVC app for example, Windsor can create a Context per Web Request. With this you don't have to write a lot of using statements throughout your code. You can read more about it here:
Windsor Tutorial - Part Seven - Lifestyles
Here's a link that explains it in more details directly from the guy that helps build the framework at Microsoft:
Entity Framework Object Context Life Cycle compared to Linq to Sql Data Context Life Cycle
You can write a test application to observe the behavior of the context tracker.
If you retrieve an entity from a context, then dispose of that context, then create a new instance of the context and attempt to save a change to the entity you retrieved earlier, it will complain that it is already tracking an entity with that ID.

Entity Framework as Repository and UnitOfWork?

I'm starting a new project and have decided to try to incorporate DDD patterns and also include Linq to Entities. When I look at the EF's ObjectContext it seems to be performing the functions of both Repository and Unit of Work patterns:
Repository in the sense that the underlying data level interface is abstracted from the entity representation and I can request and save data through the ObjectContext.
Unit Of Work in the sense that I can write all my inserts/updates to the objectContext and execute them all in one shot when I do a SaveChanges().
It seems redundant to put another layer of these patterns on top of the EF ObjectContext? It also seems that the Model classes can be incorporated directly on top of the EF generated entities using 'partial class'.
I'm new at DDD so please let me know if I'm missing something here.
I don't think that the Entity Framework is a good implementation of Repository, because:
The object context is insufficiently abstract to do good unit testing of things which reference it, since it is bound to the DB access. Having an IRepository reference instead works much better for creating unit tests.
When a client has access to the ObjectContext, the client can do pretty much anything it cares to. The only real control you have over this at all is to make certain types or properties private. It is hard to implement good data security this way.
On a non-trivial model, the ObjectContext is insufficiently abstract. You may, for example, have both tables and stored procedures mapped to the same entity type. You don't really want the client to have to distinguish between the two mappings.
On a related note, it is difficult to write comprehensive and well-enforce business rules and entity code. Indeed, whether or not it this is even a good idea is debatable.
On the other hand, once you have an ObjectContext, implementing the Repository pattern is trivial. Indeed, for cases that are not particularly complex, the Repository is something of a wrapper around the ObjectContext and the Entity types.
I would say that you should look at the ObjectContext as your UnitOfWork, and not as a repository.
An ObjectContext cannot be a repository -imho- since it is 'to generic'.
You should create your own Repositories, which have specialized methods (like GetCustomersWithGoldStatus for instance) next to the regular CRUD methods.
So, what I would do, is create repositories (one for each aggregate-root), and let those repositories use the ObjectContext.
I like to have a repository layer for the following reasons:
EF gotcha's
When you look at some of the current tutorials on EF (Code First version), it is apparent there's a number of gotcha's to be handled, particularly around object graphs (entities containing entities) and disconnected scenarios. I think a repository layer is great for wrapping these up in one place.
A clear picture of data access mechanisms
A repository gives a specific picture as to how the BL is accessing and updating the data store. It exposes methods that have a clear single purpose, and can be tested independently of the BL. Standard example from the textbooks, Find() to find a single entity. A more application specific example, Clear() to clear down a db table.
A place for optimizations
Inevitably you come up against performance hits when using vanilla EF. I use the repository to hide the optimization mechanisms from the BL.
Examples,
GetKeys() to project cached keys from the tables (for Insert/Update decisions). The reading of key only is faster and uses less memory than reading the full entity.
Bulk load via SqlBulkCopy. EF will insert by individual SQL statements. If you want a single statement to insert multiple rows, SqlBulkCopy is a good mechanism. The repository encapsulates this and provides metadata for SqlBulkCopy. As well as the Insert method, you need a StartBatch() and EndBatch() method, which is also an argument for a UnitOfWork layer.