62

It seems that lazy loading is enabled by default in EF4. At least, in my project, I can see that the value of

dataContext.ContextOptions.LazyLoadingEnabled

is true by default. I don't want lazy loading and I don't want to have to write:

dataContext.ContextOptions.LazyLoadingEnabled = false;

each time I get a new context. So is there a way to turn it off by default, say, across the whole project?

Craig Stuntz
  • 123,797
  • 12
  • 247
  • 268
Mike Chamberlain
  • 29,972
  • 27
  • 103
  • 151

5 Answers5

69

The following answer refers to Database-First or Model-First workflow (the only two workflows that were available with Entity Framework (version <= 4.0) when the question was asked). If you are using Code-First workflow (which is available since EF version >= 4.1) proceed to ssmith's answer to this question for a correct solution.


The edmx file has in the <ConceptualModel> and <EntityContainer> definition an attribute for lazy loading where you can set lazy loading generally to false:

<EntityContainer Name="MyEntitiesContext" annotation:LazyLoadingEnabled="false">

This creates the following setting in the ObjectContext constructor:

public MyEntitiesContext() : base("name=MyEntitiesContext", "MyEntitiesContext")
{
    this.ContextOptions.LazyLoadingEnabled = false;
    OnContextCreated();
}

My example is not meant that way that the generated ObjectContext (or DbContext in newer EF versions) should be edited manually (which would be overwritten with every model update from the database, as ctorx pointed out) but that the EntityContainer element in the edmx:ConceptualModels section of the EDMX file should be edited by adding the annotation:LazyLoadingEnabled="false" attribute - either manually in an XML editor or on the properties page of the designer surface where this option is available as well, Right-Click EDMX then Properties.

enter image description here

This modification of the EDMX file will automatically generate the context class with the disabled lazy loading option in the constructor like shown above. The EDMX file modification itself does not get overwritten when the model is updated from the database.

its4zahoor
  • 1,227
  • 1
  • 11
  • 17
Slauma
  • 167,754
  • 56
  • 385
  • 407
  • 16
    This requires you to modify the generated code, which will get overwritten if you modify your model. Consider putting an ObjectContextFactory in place, and make the change in the factory. That way you're still only setting the option once and you're not changing auto generated code. – ctorx Mar 07 '11 at 05:28
  • @ctorx - AFAICT a simpler option than the factory would be to just implement the partial OnContextCreated to turn lazy loading off? Or am I missing something? – James Manning Jun 11 '13 at 21:36
  • The factory can also serve to allow explicitly provided connection strings, on demand or conditionally via dependency injection so the added abstraction, in my opinion justifies the factory, even though technically, it is not necessary. – ctorx Jun 13 '13 at 15:31
  • @ctorx: More than two years later and after I even upvoted your comment because I thought your critic was absolutely right, now I understand my own answer again which actually doesn't require to modify generated code at all :) See the Edit section at the bottom of my answer. – Slauma Aug 29 '13 at 20:06
  • 1
    I'm marking your answer the accepted again to try to clear up any confusion (or perhaps it will just create more!). – Mike Chamberlain Aug 28 '14 at 23:32
64

I wrote a quick sample showing how the new Lazy Loading features work with EF Code First. Achieving what you want in the Code First model is simply a matter of adding one line to your DbContext's constructor, like so:

public BlogContext()
{
    this.Configuration.LazyLoadingEnabled = false;
}
ssmith
  • 6,039
  • 5
  • 42
  • 70
  • 11
    Not that it matters much, but both `: base()` and `this.` are redundant in this code. – Ben Lesh Oct 07 '13 at 01:04
  • In terms of functionality, yes, in terms of readability I think it's useful at times to include `this`. I agree on `base()` though, I can't think of a reason to add that. – Jeff Bobish Dec 04 '15 at 15:57
  • Yeah, not sure why base() was ever in that. Removed. – ssmith Dec 04 '15 at 19:50
  • base() is used to specify the connection string to use, right? Isn't it redundant only if you aren't specifying one? – cr1pto May 19 '16 at 17:44
24

If you may be using EF4 Code First, yeah? So, in the Initialization of your context, there is the override of 'OnModelCreated'.

In this method, I simply called up and set the property and all was resolved.

protected override void OnModelCreating(DbModelBuilder modelBuilder) {
     base.Configuration.LazyLoadingEnabled = false;
}

My model is now much more palatable. Lazy loading is great...but not when you don't want it. And when you start having circular references, it's just ridiculous.

Slauma
  • 167,754
  • 56
  • 385
  • 407
beauXjames
  • 7,565
  • 3
  • 42
  • 65
  • 4
    This won't work because it will disable lazy loading only for the context instance that builds the model (usually the first used instance after application start). For all later context instances `OnModelCreating` isn't called and `LazyLoadingEnabled` will have the default value - which is `true`. – Slauma May 07 '13 at 13:26
  • @Slauma - I hit the exact same issue today, and I've edited this answer (since it's the accepted one) to change it to setting it in the ctor instead. If I had the power to change the accepted answer from this one to yours, I'd do that instead. :) – James Manning Jun 11 '13 at 21:34
  • 1
    @JamesManning: This question has a weird history. My answer was accepted til few months ago. But my answer is not good (ctorx critic is very valid). Then the question owner moved the accept to this one which was plain wrong until your edit. Moreover it's an answer for `DbContext` which came out much later than the question was asked and the code snippets in the question are still for `ObjectContext`. Now you've edited it to a correct answer for `DbContext` but it's the same now like ssmith's answer which is more than a year older. But both aren't an answer for `ObjectContext`. Pretty crazy :) – Slauma Jun 11 '13 at 22:40
  • @Slauma - crazy indeed! If your answer is only 'off' by the ctor regenerating, is editing it to do the LazyLoadingEnabled = false in a "partial void OnContextCreated()" method in a partial class for MyEntitiesContext the 'right' fix/change for it? Sorry about this - I probably should have just left it all alone. :) – James Manning Jun 12 '13 at 03:08
  • @JamesManning: Yes, sounds good. If you make your own answer with that idea it would be the best and should probably be the accepted one :) You can also edit my answer... whatever you like. – Slauma Jun 12 '13 at 10:41
  • @JamesManning: I decided to roll back your edit to the former answer. In another context I browsed on meta to see what's the consensus and it seems to be that the *meaning* of an answer should not be changed by any other than the owner of the answer him/herself (example: http://meta.stackexchange.com/a/107512/174063 + the other answer there). Comments weren't understandable anymore after your edit. All other answers here are correct, so it shouldn't be difficult for someone to find a solution. If we're convinced that an answer is incorrect we should indicate it with comments and/or downvotes. – Slauma Aug 29 '13 at 20:48
23

You also can do it from the designer. Just open the .edmx file, right-click anywhere on the model and choose Properties. Then set the LazyLoadingEnabled to false. enter image description here

SerjG
  • 2,756
  • 3
  • 24
  • 25
Amin Saqi
  • 17,037
  • 7
  • 43
  • 68
4

If you are modelling code-first, simply remove the virtual keyword on your reference/object properties. Having virtual on a reference will enable LazyLoading on that particular reference.

Todd
  • 14,946
  • 6
  • 42
  • 56