Entity Framework not loading reference and collection properties lazily

I have Backpack and Book objects. Backpack book links (one to many). I am creating a copy of a backpack and a bunch of books. So in this case, the backpack has a bunch of books. I am saving these objects to db. I check that they were saved in db. When I try to load the backpack, it loads fine and all properties are set except for the navigation properties. I also check that LazyLoading is not disabled. My navigation properties have the virtual keyword. I'm not sure what I am doing wrong. If I try to load the backpack using Include (), it loads the books:

dbContext.Backpacks.Where(b=>b.Name!="").Include("Books").FirstOrDefault()

      

I'm trying to figure out why it doesn't load books lazily? I have the same problem downloading a book. When I download the book, it doesn't have the included backpack. I see the BackpackId is there.

In my getter / setter function, I have some logic that will run, but I don't know how that might be the problem.

+3


source to share


3 answers


After days of debugging, finally figured out the problem. As mentioned above, you must enable LazyLoading and ProxyCreating. I had problems even after enabling LazyLoading and ProxyCreating. Also make sure you specify your navigation properties as virtual

, otherwise EF won't be able to load objects lazily.

So the problem was that EF was not breaking Proxies due to my object not having a public or protected NO parameterless constructor. After creating a public (in my case protected) constructor with no parameter, it worked.



NOTE. Lack of a public / protected constructor without parameters will not affect heavy load.

Here is a link that explains the requirements for LazyLoading

+3


source


With limited information, I see the following explanations for your problem.

Lazy Loading or Proxy Creation Disabled

Make sure lazy loading and proxy creation is enabled, the former won't work without the latter.

dbContext.Configuration.ProxyCreationEnabled = true;
dbContext.Configuration.LazyLoadingEnabled = true;

      

(see this post for details )

Accessing Objects After Deleting Context



Simplified, Lazy Loading works like this:

  • Whenever you retrieve an entity from context, you actually end up with an auto-generated subclass of the class you expected, which overrides your navigation properties virtual

    , which is a proxy .
  • Whenever you access the specified navigation properties, the proxy will access the database and load related objects when needed.

This last step is, of course, only possible if the object / proxy is still attached to the context and therefore can query the database to retrieve the specified objects.

using( var dbContext = new MyContext() )
{
    dbContext.Configuration.ProxyCreationEnabled = true;
    dbContext.Configuration.LazyLoadingEnabled = true;
    // Note: You can modify or derive from `MyContext` so that this is
    //       done automatically whenever a new `MyContext` is instantiated

    var backpack = dbContext.Backpacks.Where(b=>b.Name!="").FirstOrDefault();

    // This should work
    var firstBook = backpack.Books.FirstOrDefault();
}

// This will probably not, because the context was already disposed
var firstDrink = backpack.Drinks.FirstOrDefault();

      

I hope this helps, but feel free to provide more information if it is not

+3


source


The desired download is achieved using the method Include()

, and as a result, you force the download to be loaded using Include("Books")

.

Change this:

dbContext.Backpacks.Where(b=>b.Name!="").Include("Books").FirstOrDefault()

      

:

dbContext.Backpacks.Where(b=>b.Name!="").FirstOrDefault()

      

You should now see what Books

no longer looks like loading.

Reference:

+1


source







All Articles