Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding Entity Framework contexts

Through various questions I have asked here and other forums, I have come to the conclusion that I have no idea what I'm doing when it comes to the generated entity context objects in Entity Framework.

As background, I have a ton of experience using LLBLGen Pro, and Entity Framework is about three weeks old to me.

Lets say I have a context called "myContext". There is a table/entity called Employee in my model, so I now have a myContext.Employees. I assume this to mean that this property represents the set of Employee entities in my context. However, I assume wrong, as I can add a new entity to the context with:

myContext.Employees.AddObject(new Employee());

and this new Employee entity appears nowhere in myContext.Employees. From what I gather, the only way to find this newly added entity is to track it down hiding in the myContext.ObjectStateManager. This sounds to me like the myContext.Employees set is in fact not the set of Employee entities in the context, but rather some kind of representation of the Employee entities that exist in the database.

To add further to this confusion, Lets say I am looking at a single Employee entity. There is a Project entity that has a M:1 relationship with Employee (an employee can have multiple projects). If I want to add a new project to a particular employee, I just do:

myEmployee.Projects.Add(new Project());

Great, this actually adds the Project to the collection as I would expect. But this flies right in the face of how the ObjectSet properties off of the context work. If I add a new Project to the context with:

myContext.Projects.AddObject(new Project());

this does not alter the Projects set.

I would appreciate it very much if someone were to explain this to me. Also, I really want a collection of all the Employees (or Projects) in the context, and I want it available as a property of the context. Is this possible with EF?

like image 525
Mike Gates Avatar asked Apr 26 '10 19:04

Mike Gates


People also ask

Where is DbContext in Entity Framework?

DbContext is an important class in Entity Framework API. It is a bridge between your domain or entity classes and the database. DbContext is the primary class that is responsible for interacting with the database.

What is database context in Entity Framework?

A DbContext instance represents a combination of the Unit Of Work and Repository patterns such that it can be used to query from a database and group together changes that will then be written back to the store as a unit. DbContext is conceptually similar to ObjectContext.

Can we have multiple DbContext in Entity Framework?

Multiple DbContext was first introduced in Entity Framework 6.0. Multiple context classes may belong to a single database or two different databases.

Where do I put DbContext?

To have a usable Entity Framework DBContext, we need to change the configuration of the application. We will need to add a connection string so that our DBContext knows which server to go to and which database to query. We will put the connection string in a JSON configuration file.


1 Answers

An ObjectSet is a query. Like everything in LINQ, it's lazy. It does nothing until you either enumerate it or call a method like .Count(), at which point a database query is run, and any returned entities are merged with those already in the context.

So you can do something like:

var activeEmployees = Context.Employees.Where(e => e.IsActive)

...without running a query.

You can further compose this:

var orderedEmployees = activeEmployees.OrderBy(e => e.Name);

...again, without running a query.

But if you look into the set:

var first = orderedEmployees.First();

...then a DB query is run. This is common to all LINQ.

If you want to enumerate entities already in the context, you need to look towards the ObjectStateManager, instead. So for Employees, you can do:

var states = EntityState.Added || EntityState.Deleted || // whatever you need
var emps = Context.ObjectStateManager.GetObjectStateEntries(states)
                                     .Select(e => e.Entity)
                                     .OfType<Employee>();

Note that although this works, it is not a way that I would recommend working. Typically, you do not want your ObjectContexts to be long-lived. For this, and other reasons, they are not really suitable to be a general-purpose container of objects. Use the usual List types for that. It is more accurate to think of an ObjectContext as a unit of work. Typically, in a unit of work you already know which instances you are working with.

like image 87
Craig Stuntz Avatar answered Oct 06 '22 18:10

Craig Stuntz