Note: This is a follow up of What is the overhead of Entity Framework tracking? which asks about a rather old version of Entity Framework.
One of the team I am working with have used no tracking behavior at global level rather than at context or query level. This lead to strange code in the repositories since all injected context instances are not tracked: adding requires manual attaching, update has to explicit and some other explicit code related to navigation properties.
When asked about this, they invoked performance reasons, but failed to indicate a source.
My solution would be to use no tracking at context instance level. This would remove virtually all cumbersome code related to saving changes and the only issue would be when the programmer forgets to set no tracking for the instance. My assumption is that would not be such a big deal under normal circumstances (trees of several hundreds models).
This article suggests a big difference (both memory and CPU) between systematic usage of no tracking and everything tracked, but it is not clear if this only related to this (the difference seems much bigger than just the cloned data required for tracking).
Question: What is the overhead of tracking in Entity Framework 3.1?
What is the overhead of tracking in Entity Framework 3.1?
It's exactly the same as attaching every entity you query to the change tracker manually.
You can also opt-in to tracking for a single query with .AsTracking().
Related
Looking at eShopOnContainers, the microservice reference architecture from Microsoft. I see that for each service, in Program.cs a call is made to host.MigrateDbContext. This, in turn, executes all of the EF migrations for the given context.
In a real-world orchestrator isn't is possible that numerous containers for the same service could be spun up almost simultaneously? And if that happened, isn't it likely that multiple containers trying to execute the same migrations would deadlock or cause other issues?
Is this something that wasn't dealt with because it is beyond the scope of a reference project or does EF have something built in to handle concurrency that I'm not seeing?
I've found that there are numerous approaches to this problem, each with their own strengths and weaknesses. Some are straightforward... bringing the entire app down, updating schema, and then bringing the app back online. Some implement the schema changes as a series of smaller changes, each of which are both forward and backward compatible, allowing zero downtime. Still others leverage built-in or third-party tools written specifically to address this task.
So, to answer my own question, this topic was almost certainly omitted because it was beyond the scope of the eShopOnContainers project/eBooks. The right choice for you will vary based on your project's size, complexity, acceptable downtime, etc.
I am beginning to wonder if ANYONE uses NHibernate with a WPF or Win Forms application, such is the dearth of examples or text books on the subject. I am struggling to find "best practices" for its use, and especially session and sessionfactory management, with an MVVM WPF application and repositories.
To jump right in, it seems that the preference is to supply the repository with an ISession. But, where is this instantiated - in the ViewModel? - and if so, does this not created an uncomfortable dependency between the VM and NH (or is that just simply unavoidable, no matter how you dress it up?) Any implications for a multi-user application?
With the repository pattern - should I use one large repos. for all objects (and hence one session) or, as seems more manageable at first sight, should the repositories be split up in some logical business-related way? - but, if split up, how then to manage sessions? In my case, a form/window does not just deal with one entity (maybe it should...?) but with more than one. I don't want the ORM side to be dictated by the UI form design (maybe it should!?)
And then again, SessionFactory - where, and when to create it - once, at app startup?
Any good pointers or references for an NH app that is not web-based would be much appreciated.
Here is a reference to a similar question, but it was posed over four years ago: Using Unit of Work design pattern / NHibernate Sessions in an MVVM WPF
Many thanks
I've been using NHibernate with MVVM for years, once you get it going it's great. The MSDN article Building a Desktop To-Do Application with NHibernate covers the whole issue of session management rather well and is definitely worth a read.
One thing that will make life a lot easier is the use of a good dependency injection framework. I personally use Ninject and one of the things I particularly like is its support for object scoping. For example you can set your NHibernate session object (and thus the entity repositories) to scope to the pages in your application using InScope, so anything within the hierarchy of a given page that asks the injection framework for a session object will all get a pointer to the same instance.
Lots of other advantages to going down this route, for example it's very easy to use things like Castle Dynamic Proxy to inject property change notification to classes so that the entities you get back from your database queries support it automatically and thus can be bound to directly in the view or subscribed to by other class instances in your model or view model. Same goes for lists, which can be problematic because replacing a database entity list with an ObservableCollection<> can cause the database to think the entire list has changed which in turn causes performance problems when every single entity starts serializing itself back to disk regardless of whether or not it has actually changed.
We have an app in ASP.NET MVC 3 that, due to legacy and porting reasons, is written entirely using traditional ADO.NET for the data layer.
I am now tasked with adding some reporting to this website, and the reports can result in some extremely complicated queries.
Are there any pitfalls in using the EF Power Tools to reverse-engineer a code first model and using it side-by-side with our current ADO.NET model? Doing so would allow me to use LINQ for querying the data I need, greatly speeding up the time required to write each report. I would need to shut off data context initialization, as we have our current model do that, but are there any glaring risks or problems associated with trying to do this?
If it's of any relevance (I know EF 5 has a ton of new features), we are using .NET 4 and will begin moving to .NET 4.5 as soon as it launches.
I think this is a very sensible thing to do. You could also use a database-first model, which you can refresh whenever the database changes and which does not try to initialize a database.
Since you will use the context read-only you can optimize the query process by setting the MergeOption property of ObjectQuerys to MergeOption.NoTracking. This reduces overhead because the context will not track changes of the generated objects.
A problem might be that there is more maintenance if the database changes, but I think the absence of walls of boiler-plate query code for reporting on the old data layer far outweighs that.
One day :) you may even decide to use the EF model to display data that users want to filter in the UI and use the old data layer for CUD commands. (a bit like CQRS).
I've built a site in MVC3 using EF 4.0 using the Repository pattern. Everything was going good but I'm starting to run into a lot of "The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects" errors. It seems that my repository layer is getting the contexts all mixed up, so I figured it might just be easier to start a new EF4.1 project.
At first I looked into Repository Pattern + Unit of Work, but came across some threads saying that this isn't needed for EF4.1. I came across this thread saying "DbContext is implementation of unit of work pattern and IDbSet is implementation of repository pattern.". I figured maybe then I could just use that. Upon further inspection though it seems that DbContext uses the Code First approach, which as far as I can tell will drop and create the database again if the POCOs change. I need to keep the data in my database, so as far as I can tell that option is out.
My head is spinning right now with EF options. Is the Repository pattern needed with EF4.1? Is DbContext meant for working on databases that are already full of data? Is there a better way of managing the entity contexts that don't involve these?
Any push in the right direction would be great =/
A few comments. For details I recommend to do some basic research using a search engine.
...I'm starting to run into a lot of "The relationship between the two
objects cannot be defined because they are attached to different
ObjectContext objects" errors. It seems that my repository layer is
getting the contexts all mixed up, so I figured it might just be
easier to start a new EF4.1 project.
If you have this error you did something wrong. EF 4.1 won't protect you to do the same mistake again because you also cannot change relationships between objects that are attached to different DbContexts. You just have to analyze and debug your code and find the source of the problem.
...this thread saying "DbContext is implementation of unit of work
pattern and IDbSet is implementation of repository pattern.". I
figured maybe then I could just use that...
ObjectContext and ObjectSet<T> is an implementation of those patterns as well. This is no reason to change the version of Entity Framework.
Upon further inspection though it seems that DbContext uses the Code
First approach...
You can also use Database First and Model First approach with DbContext.
...which as far as I can tell will drop and create the database again
if the POCOs change. I need to keep the data in my database, so as far
as I can tell that option is out.
You can turn that feature off. Also, EF 4.3 has a migration feature which helps to update and evolve an existing database schema.
Is the Repository pattern needed with EF4.1?
No. It's also not needed for ObjectContext. To be precise, it's not needed that you write your own (abstract) repository of top of EF, because EF is already an implementation of that pattern.
Is DbContext meant for working on databases that are already full of
data?
Yes. The additional feature to create a database from code (Code-First) is mainly a productivity tool for the development phase of your application which is supposed to be disabled in production.
This question pertains to writing a massively scalable & efficient customer sessionstate class library in C# and I am in desperate need of sage counsel.
Original thread that has been guiding me based upon:
I just discovered why all ASP.Net websites are slow, and I am trying to work out what to do about it
Hope this thread can be called back from the netherworld as I have been spending the past 48 hours (with a few power naps) trying to implement the ideas elucidated here and I must admit I am somewhat lost in the solution space and would be grateful for some clarity.
Allow me to explain where I am at & what is confusing me & what I am trying to accomplish. The back & forth here with James & Joel raises great points but concrete implementations beyond the links leave me somewhat in the dark.
I'm trying to create a class library/dll I can use in several of my projects to bypass the default sessionstate options of inproc, sql & stateserver. This is somewhat new to me so please excuse my ignorance. Further I am somewhat of a down & dirty asp.net / C# coder and some of the more subtle nuances of generics, thread safety, locking, and serialization do tend to hurt my little head :))
I had started by creating a custom sesion state provider based upon a sample I found on MSDN that writes to access. Then I had found this page and Pandora's box was wide open and now I cannot get the genie back in the bottle. I dug more and I found a template for a custom sessionstate module and I added that too to my class library. SO nowwwww... I have both a provider and module of my own and then after reading Joel's many tips I ended up creating a custom session state items collection based upon yet another sample I found on MSDN.
That was originally based upon a hashlist, somehow I ended up turning it into a sortedlist, and then I seem to have followed Joel's steps one by one as pertains to the following:
lock(typeOf) rewritten in all .cs files to use lock(thisLock) where thisLock is a private static object as per the Rico article mentioned here ... I do understand the "concept" of deadlocks but this is my first attempt to scale an asp.net site and I am not feeling like Joe Architect quite yet. I cannot afford to be lazy here because I do not wish to build upon a shaky foundation only to get a bunch of hard to figure out bugs further on up the road.
Then I followed Joel's advice about the "slim" version of the locks and got that working in my classlib as well. And yet still my spider-sense is tingling telling me I basically still am in obedience mode rather than enlightenment mode, i.e. I don't have the NEO style vision of 1s & 0s dancing in my perceptual field.
So I keep coming back to this page like a refugee from a Dan Brown novel and now I am looking at the final admonition by Joel advising that until the sessionstateitem collection is made threadsafe no good can be assured in the multiverse. So I figure it is time to start brushing up on threadsafe collections.
That's when I start reading an article by MSFT on http://msdn.microsoft.com/en-us/library/dd997305.aspx SortedLists & other oldies but apparently not so goodies being deprecated in favor of generics. Now I have actually created entire business layers and linq layers that are serializable and are used for shopping carts and stored in an offline database.
But the truth is sessionstate, threadsafety, using BOTH module & provider, and the lack of any samples here to debug has my cerebral drive continuously redlining and the heat sink is faltering.
MSFT says in above link, "The collection classes introduced in the .NET Framework 2.0 are found in the System.Collections.Generic namespace. These include List, Dictionary, and so on. These classes provide improved type safety and performance compared to the .NET Framework 1.0 classes. However, the .NET Framework 2.0 collection classes do not provide any thread synchronization; user code must provide all synchronization when items are added or removed on multiple threads concurrently.
We recommend the concurrent collections classes in the .NET Framework 4 because they provide not only the type safety of the .NET Framework 2.0 collection classes, but also more efficient and more complete thread safety than the .NET Framework 1.0 collections provide.."
So James sorta bolted thru the exit saying I got it, and that's the end of the thread but I have experienced some very peculiar behavior while debugging.
I am using a harness website to test my session lib. If I specify BOTH the httpmodule and the custom provider only the module runs in the harness/testing site I whipped up. BUT- if I modify the web.config of a real mature codebase it opts for the provider.
I did realize I could use one at a time to get the harness site pointing to the provider by not using the module.
That is fine for now but then I found myself saying to myself, "self.... you have a custom collection but is it threadsafe, are we still locking it, should we be locking it from outside the collection, i.e. in module or provider? My brain is saying is "thread-safety" encapsulated in the collection itself.
And how do I really know that all these slow page.aspx/longpage.aspx samples where one must hang out waiting for a thread to finish, even if user has click another link in frustration (what frustration? on a web site? perish de thought!)...
So basically, like Bugs Bunny, hangin' from the smithereen remnants of la bella luna I beseech thee, "GET ME OUTTA HERE..."
I thank you in advance for your timely consideration in this matter & others of monumental importance.
Best,
Cary Abramoff, MCSD.NET (Ten years of .net & I still wish it were all JQUERY baby!)
Sounds like what you really need to do next is create a testing program that calls multiple pages in your harness site simultaneously. This will simulate the situation that locking is meant to benefit and it will also help you determine if your implementation is logically correct. Without that I think you're sort of working at this blindly.
Hope that helps.
On a side note: I am currently working on a custom session state provider backed by Redis. My plan is to have an implementation that allows the locking to be turned off. I will likely get open sourced on Github once it is stable.