I am reading this E.F. Team Blog's this series http://blogs.msdn.com/b/adonet/archive/2011/01/27/using-dbcontext-in-ef-feature-ctp5-part-1-introduction-and-model.aspx
At many places i saw this term "Entity Tracked by Context", specially in this part http://blogs.msdn.com/b/adonet/archive/2011/01/29/using-dbcontext-in-ef-feature-ctp5-part-4-add-attach-and-entity-states.aspx (part4)
My questions are
What does "Entity Tracked by Context" mean??
Does same context is used for every request or new context is created for each request (I am using E.F. for Asp.Net MVC APP)
Tracking every entity (loaded) must be adding some memory-overhead on server, is it??
"Entity Tracked by Context" mean that context is aware of the entity, it knows state of the entity and changes made to the entity. Context can work only with tracked entities. If you call save changes only changes on tracked entities will be persisted to the database. Tracked and Attached can be considered as synonyms.
In EF we are usually talking about attached entities and detached entities. Attached entities are tracked by the context. Entity become attached if you load it from database (unless you manually for EF to don't track the entity) or if you call Attach or Add (DbContext API) / AddObject (ObjectContext API) for the entity. You can force entity to detach from the context either by calling Detach (ObjectContext API) or setting the state to Detached (DbContext API). If you just create the entity in your code as any other class it is considered as detached until you call Attach for it.
New context is always created for each request - web application works a lot with detached entities. That will also solve the issue with memory. If you detach all entities you want to store in some state (like session) and if you dispose the context correctly in each request you will free the memory.
Related
Some of you may be familiar with the DbContextScope library, which allows you to nest scopes within your code, and allow those scopes to share a common DbContext. The idea is that the DbContext gets managed for you by the scope library, and instead of calling SaveChanges() on the context, you call SaveChanges() on the scope. The magic happens because the scope will only save all the changes on the context at it's outer-most call of SaveChanges(), so all the nested operations performed on the DbContext get saved in a single transaction at the outer scope-level.
Now that DI is a first-class citizen in .NET Core, it appears that scopes have also become an important part of the .NET Core ecosystem, and the EF Core team, knowing this, has implemented scoping based on allowing DbContexts being injected by the DI system, and (I assume) allowing change saving to happen at scope-levels and not directly on the DbContexts in some way.
So my question are these:
What is the appropriate way to share a DbContext via a scope, allowing the SaveChanges() be managed at the scope level and not the code-level that typically calls SaveChanges() on the DbContext?
Are there new mechanisms in EF Core that manage this for you, just like DbContextScope did this for you as a 3rd party library?
Save me the drama, and spare me the lectures on why you think UOW needs to be implemented in addition to EF. K thnxs bye.
UPDATE: As of 6/2020 there are several forks of DbContextScope that work with EF Core 3.
UPDATE: Forks of this project can be viewed here: https://github.com/mehdime/DbContextScope/network
There are several EF Core 3 versions... I haven't tried any yet, but there you go.
Since Entity Framework 5.0.0, there is IDbContextFactory<TDbContext> that lets you control the creation and disposal (!!) of your DbContexts.
Instead of registering your DbContext with AddDbContext or AddDbContextPool, you can now use AddDbContextFactory or AddPooledDbContextFactory, respectively.
Note that this feature takes care of one of the problems that DbContextScope solves, not all of them. As for what the other problems and solutions are, refer to Mehdi's original post. It is long but excellent.
DbContext sharing is built-in to the Dependency Injection design for EF.
The DI container will generate a scoped DbContext instance for each web request. You can share the DbContext instance from any component that has a dependency on it, and call SaveChanges(), or manage transactions in your outer controller.
I have a service that use EF 6.1.3 to access to the database. I have POCO entities to store the results of EF, but the resutls are dynamicProxies instead of the POCO entity.
The problem is that when the service try to send to the client this dynamic proxy, I get an error receiving the http response.
I have tried to disabled the creation of the proxies entities in my dbContext, and then I receive my real POCO entity so I have no problems.
But really I don't know what is dynamic proxies and when is usuful to use them and when I can disabled them.
EDIT: I have disabled lazy loading.
Thanks.
When creating instances of POCO entity types, the Entity Framework
often creates instances of a dynamically generated derived type that
acts as a proxy for the entity. This proxy overrides some virtual
properties of the entity to insert hooks for performing actions
automatically when the property is accessed. For example, this
mechanism is used to support lazy loading of relationships.
Source: https://msdn.microsoft.com/en-us/data/jj592886.aspx
You will find everything you need in the above article!
My understanding is that the convention is to use the Entity Framework Fluent API in side of the overridden OnModelCreating method in your DBContext method; and that this is only run during db creation.
This would leave me to believe that the Fluent API can only be leveraged more than once(for instance while you're developing your db) if you are dropping and creating your database everytime there are changes.
My question is: Is there a way to leverage the Fluent API for db configuration, for database updates only, for example while running the database migration command "update-database"?
From the DbContext.OnModelCreating documentation:
Typically, this method is called only once when the first instance of a derived context is created. The model for that context is then cached and is for all further instances of the context in the app domain.
So it is called when the model is created, not just when the database is created. That will happen when you call Update-Database after adding a migration, or when you start up your website after publishing a new version.
References:
https://stackoverflow.com/a/6181867/150342
http://elegantcode.com/2012/04/12/entity-framework-migrations-tips/
I need to retrieve a large graph of entities, manipulate it in the UI (adds, updates, deletes), then persist it all back to the database. After various SO questions and experiments, I'm finding this mass "detached graph update" approach to be very problematic, so I'm now rethinking my approach.
It's only a 2-tier WPF app, so I'm now thinking of having a long-running context that exists for the duration of the UI used to manipulate the entity graph - that way it can track changes automatically. However I'm not sure how to approach this architecturally.
The application currently has three projects - the UI, business tier, and one for the edmx & generated entities. My business tier has a CustomerManager class that exposes a method to retrieve a Customer graph (orders, order lines, etc.), and a method to persist the Customer graph. Assuming that the UI holds on to the same instance of the CustomerManager class, and therefore the same context, changes to the graph (adding and changing entities) will be tracked.
Deleting an entity is a bit more tricky, as the context must be used to do this, i.e.:-
context.Set<Order>().Remove(orderToDelete);
Looking for some architectural advice really. Do I just expose a DeleteOrder method in my CustomerManager class that does this? Given that I have a dozen other entity types, I would presumably need to expose similar methods to delete orders, products, etc.
Is it a sensible approach for the UI to hold on to the same CustomerManager instance, or is there a better way to manage a long-running context? A logical place for the DeleteOrder method would be in my Customer entity (partial) class, but as these classes are in a separate project from the business tier (which is where the context resides), I guess I can't do this (unless I pass the context to the DeleteOrder method)?
Your long living context idea will work only if your context lives in UI and UI talks to database directly to get and persist data. Involving WCF between your UI and context always result in serialization and it causes entity detaching = not tracking changes (unless you use STEs). Having long living context in WCF service is too problematic and in general bad practice.
Have you considered WCF Data Services? They provide client side tracking to some extend by using special client side context.
I've been using the entity framework in combination with the self tracking entity code generation templates for my latest silverlight to WCF application. It's the first time I've used the entity framework in a real project and my hope was that I would save myself a lot of time and effort by being able to automatically update the whole data access layer of my project when my database schema changed.
Happily I've found that to be the case, updating my database schema by adding a new table, changing column names, adding new columns etc. etc. can be propagated to my business object classes by using the update from database option on the entity framework model.
Where I'm hurting is the CRUD operations within my WCF service in response to actions on my Silverlight client. I use the same self tracking entity framework business objects in my Silverlight app but I find I'm continually having to fight against problems such as foreign key associations not being handled correctly when updating an object or the change tracker getting confused about the state of an object at the Silverlight end and the data access operation within the WCF layer throwing a wobbly.
It's got to a point where I have now spent more time dealing with this quirks than I have on my previous project where I used Linq-to-SQL as the starting point for rolling my own business objects.
Is it just me being hopeless or is the self tracking entities approach something that should be avoided until it's more mature?
What version of self tracking entities are you using?
I'm using the .Net 4.0 version together with visual studio 2010. All CRUD operations work fine, also operation with FK.
I had problems in VS 2008 with FK but that's gone in VS 2010 with .Net 4.0.
If you want, I can provide you some samples.
Greetings
Since STE entity does not support lazy loading you should use Include on the server side include related properties. There is no way to include all related navigation properties. You have to explicitly include the properties. for instance
//server side
customer.Include("Orders.OrderDetails").Include("Address")