I am new to Entity Framework 4.0, using it with C#, and currently experimenting with its features.
What I noticed is that, like with most similar ORMs, it relies on an Context object to deal with the data-manipulation and CRUD statements generation done on the generated entities.
This means that if I want to save the changes back to the database, I always need to be able to have access to a reference to the ObjectContext that has instanciated the entities.
It is fine and all if the context has been created in an accessable scope (same method, for example), but what if I pass an entity or and entity set to a method and want this method to save the changes? It looks like the only easy way is to pass the ObjectContext along with the parameters.
Another solution would be placing the ObjectContext in some sort of global variable.
Needless to say, I find styling and maintainability issues to both of these approaches.
In short, the best way I can imagine is getting a reference to the ObjectContext from the entity or entity set.
I know that it isn't possible by default.
I have found a method showing adding an extension method to get the ObjectContext from the entity. However, it only works for entities with relationships and calling this method is expensive according to the author.
I was thinking about maybe modifying the T4 template to add a Context property to all my entities and fill it automatically on entities' instanciation.
I have already modified T4 template once to have Entity Framework enforce Max Length on my generated classes (by following Julie Lerman's Programming Entity Framework 4 book).
I can't say I really enjoy the T4 syntax so far, but if that's the best/only way, so be it...
Has anyone already done so and what would be the best way to handle this and willing to share his T4 template or explain what are the best partial methods or events to hook into to get this done?
Is there any major downside in using such an approach?
I am thinking that having so many references to the ObjectContext may hinder/delay its ability to be recollected by the GC if some of my entities remain in scope but I actually have no use anymore for the ObjectContext.
Many thanks.
If you need to pass object context as parameter together with your entities you are doing something wrong.
Usually context is needed only in well defined layer. All classes from this layer which requires context to their logic can receive the context through some specialized class - context provider (it can also be called service locator). Context provider will hold current context instance in some storage - you can create your own or you can store it per thread, per http request, etc.
If they need more then one context instance in your classes you can modify your provider to work also as factory.
Another common approach is combined with dependency injection. You will pass the context to your classes through the constructor (or property) and you will have some bootstraper code which will do all necessary initialization for you (create required instances and pass all dependencies into them). Again you can pass a context or a factory. This is usually used together with IoC containers which will do the plumbing for you.
Once you have this infrastructure prepared you can pass your entity to the any initialized class from that layer and it will have the context available.
Related
The current retrieval pattern in my Service classes (in an ASP.NET MVC application) looks something like:
public Client Get(int id)
{
using (var repo = _repoFactory.Get<Client>())
{
return repo.Get(id);
}
}
Where _repoFactory.Get<T>() returns a repository which, when disposed, also disposes the Entity Framework DbContext;
However, when the consumer of the Get(int id) method needs to use navigation properties on the Client object, an exception is thrown because the context is already disposed.
I can foresee a few ways to negotiate this problem:
Don't use navigation properties outside of the service
Don't use lazy-loading navigation properties
Find some other way to dispose of the context when the request is finished
What is the "correct" (or least incorrect) way and how can it be accomplished?
All the ways that you suggested are "correct," and each has its advantages and disadvantages. You'll need to decide which approach you want to use.
Don't use navigation properties outside of the service
This is difficult to enforce if the service is returning entities. In my current project, we make heavy use of "DTO"s, which are new classes that represent the data that we expect to need in a given context. Because these aren't entities, we know that any property on them will be fully hydrated before it is returned from the repository.
Don't use lazy-loading navigation properties
This is roughly the same as above, except that you're allowing for the possibility of certain navigation properties to be eager-loaded. Again, how does the developer consuming this data know which properties are and are not going to be available? "DTO"s solve this problem, but they also introduce a bunch of extra classes that are almost identical to the existing entities.
Find some other way to dispose of the context when the request is finished
Usually people do this by having contexts bound in a per-request scope in their DI framework, and allow the DI framework to take care of instantiation/disposal of their contexts.
The main danger with this approach is that, while lazy-loading properties won't throw exceptions when accessed, each access requires another database round-trip. This makes it easy for developers to accidentally write code that ends up making thousands of round-trips when only two or three would be required otherwise.
However, if you have a reliable way of identifying performance issues and addressing them, then you could use this approach in the general case and then add a little eager-loading where you find it to be necessary. For example, MiniProfiler can sit on your front-end and give you information about the database round-trips you're making, as well as warnings when it notices that many database queries are practically identical.
From MSDN:
Represents a combination of the Unit-Of-Work and Repository patterns and enables you to query a database and group together changes that will then be written back to the store as a unit. DbContext is conceptually similar to ObjectContext.
I though DbContext only handle the connection to the DB and the number of threads working against the DB.
Now I understand it contains the tracking mechanism? I thought this was in the ObjectContext.
So what is (in plain English) the difference between them?
DbContext is a lightweight version of the ObjectContext class, which is laid almost right on top of ObjectContext (there is even a way to get to the ObjectContext from just the DbContext). It's also a lot easier to use, IMO, and makes CRUD operations a sinch.
For better information, who better to look to than Julie Lerman for more info on the differences, as was brought into EF 4.1.
the DbContext is a smaller API exposing the most commonly used
features of the ObjectContext. In some cases, those features are mirrored in the DbContext
API. In other cases, the Entity Framework team has simplified more complex coding
by providing us with methods like Find or properties like DbSet.Local. But there’s
a big API lurking underneath that you may still need access to. For example, you might
want to work directly with the MetadataWorkspace to write generic code against classes
because that API can read the model more efficiently than reflection. Additionally, the
MetadataWorkspace is able to provide more information about the metadata than you
can discover with reflection, for example, for Key properties. Or you might want to
take advantage of a database-specific function that is exposed through Entity SQL,
which you can’t access from LINQ to Entities.
Or you may already have an application
written using the ObjectContext and you want to leverage the DbContext in future updates
without replacing all of the ObjectContext code.(Reference from Programming DbContext)
Object Context:
1.It support compiled query
2.It support self tracking of entities
3.It available for entity frame work 4.0 and below version
4.It is not thread safe.
5.It is best for DB first and model first approach.
Database Context:
1.It does not support compiled query
2.It support not self tracking of entities
3.It available for entity frame work 4.1 and above version
4.It is thread safe for static and share member(public).
5.It is best for DB first and model first approach and code first approach.
I'm pretty new to IoC, Dependency Injection and Unit Testing. I'm starting a new pet project and I'm trying to do it right.
I was planning to use the Repository pattern to mediate with the data. The objects that I was going to return from the repositories were going to be objects collected from a Linq to entities data context (EF4).
I'm reading in "Dependency Injection" from Mark Seeman that doing it, makes an important dependency and will definitely complicate the testing (that's what he's using POCO objects in a Library Project).
I'm not understanding why. Although the objects are created by a linq to entities context, I can create them simply calling the constructor as they were normal objects. So I assume that is possible to create fake repositories that deviler these objects to the caller.
I'm also concerned about the automatic generation of POCO classes, which is not very easy.
Can somebody bring some light? Are POCO objects trully necessary for a decoupled and testable project?
**EDIT: Thanks to Yuck I understand that it's better to avoid autogeneration with templates, which brings me to a design question. If I come from a big legacy database wich his tables are assuming a variety of responsabilities (doesn't fit well with the concept of a class with a single responsability), what's the best way to deal with that?
Delete the database is not an option ;-)
No, they're not necessary it just makes things easier, cleaner.
The POCO library won't have any knowledge that it's being used by Entity Framework. This allows it to be used in other ways - in place of a view model, for instance. It also allows you to use the same project on both sides of a WCF service which eliminates the need to create data transfer objects (DTO).
Just two examples from personal experience but there are surely more. In general the less a particular object or piece of code knows about who is using it or how it's being used will make it more adaptable and generic for other situations.
You also mention automatic generation of POCO classes. I don't recommend doing this. Were you planning to generate the class definitions from your database structure?
I was planning to use the Repository pattern to mediate with the data.
The objects that I was going to return from the repositories were
going to be objects collected from a Linq to entities data context
(EF4).
The default classes (not the POCOs) EF generates contain proxies for lazy loading and are tied at the hip to Entity Framework. That means any other class that wants to use those classes will have to reference the required EF assemblies.
This is the dependency Mark Seeman is talking about. Since you are now dependent on these non-abstract types, which in turn are dependent on EF, you cannot simply change the implementation of your repository to something different (i.e. just using your own persistence store) without addressing this change in the class that depend on these types.
If you are truly only interested in the public properties of the EF generated types then you can have the partial classes generated by EF implement a base interface. Put all the properties you need in that base interface and pass the dependency in as the base interface - now you only depend on the base interface and not EF anymore.
I read in a previous article about how to resolve a solution by placing the ObjectContext of my Db in a property within HttpContext.Current.Items["Db"]; This works fantastic, however I have a question. Does this means that every time I use my repository I have to pass the ObjectContext within HttpContext.Current.Items or do I only need to do this when I am creating or updating an entity that has a reference to another entity.
Within my repository classes I have 2 ways of instantiating them, with a ObjectContext and without one in which the ObjectContext is created there within the entity.
You should share one context among all your repositories used in single HTTP request processing. You should also dispose context at the end of request processing. Generally your repository should not be dependent on HttpContext. The best way is to create ObjectContext outside of your repositories and always pass it to their constructor. You can also do that by using some IoC container like Windsor, StructureMap, Ninject or Unity.
I'm at a bit of a loss here.
I have a one-to-many relationship between Project and Task and another between Task and TaskEvent.
A Task only exists in the context of a Project and once assigned to a Project can't be changed to belong to another Project.
A business rule states that a Task can only be deleted, and therefore removed from the collection of Tasks that belong to a certain project, if the Task has no TaskEvents captured against it.
How do I specify this in Entity Framework? I'm using Self-Tracking entities, but actually I'm at a loss as to where to define this kind of rule in general. We have other rules that are db ignorant, but how does one define a business rule, preferably that exists in isolation from the entity classes as they are regenerated, as a class of their own with a single responsibility?
I'm thinking I'll have to implement some sort of validator that can use reflection to pick up these 'rule' classes based on the type of the object being validated and then have them each perform their validations.
But how do I push the object context into that? Should my validator have an instance of the object context and then pass it through to each rule as it is executed?
And even more flustering, how do I detect the deletes? Will I have to call up the old version of the Project and do a comparison of it's old tasks and current tasks and then check all the deleted ones to make sure they have not TimeEvents captured?
What are the drawbacks to this method and what else can you suggest?
EDIT: I should specify that we're using an n-tier design and both the client apps(MVC and Silverlight) hit WCF services to do anything useful. This is obviously the layer we want to implement the validation in, although if we could use those rules that aren't db specific on the clients that would be great. We're using DataAnnotations for those validations at present.
Thanks
Have a look at this.
Since you are using the n-tier design , my suggestion is to use the EF as a ORM layer rather than a full substitute for domain model. You should create a separate BLL layer that contains business rules and map the domain model to the EF classes. If the mapping is not complicated it can be done manually else you can use tools such as Automapper to perform the mapping for you.
We ended up using a service layer which encapsulated the rules and validated entities based on rule contexts.
For each action there was a context and a set of rules that were associated through the use of an attribute. All associated rules could therefore target the entity of a specific type required by the service action.
The rules were identified using reflection and tested on the service call.
Entity Framework entities still acted as a slightly thinner domain model than I would have liked but we never ran into serious issues and the tracking provided by EF actually helped make some previously impossible rules easy.