user3055099
user3055099

Reputation:

Lazy loading outside of DbContext

WebApi

Let's have a Person class with many one-to-many relations to classes like Car, Pet, Children ...

and PersonRepository where i have to include all relations and their relations or just disable lazy-loading

public Person getPerson()
{
  ...
  using (db = new DbContext())
  {
    // var person = linq-query

    // return person;
  }
  ...
}

So in my controller i have fully loaded Person with relations and their relations.

If there is array of objects with many nested relations it is inefficient and memory demanding.

How i can lazy-load properties outside of repository or what is general solution to this problem?

Upvotes: 2

Views: 665

Answers (4)

CodeNotFound
CodeNotFound

Reputation: 23190

How i can lazy-load properties outside of repository or what is general solution to this problem?

If you mean to know how to load navigational properties after disabling Lazy Loading on your context, then you have the following solutions:

  • Eager Loading by using Include methode of your DbSet like this:

    db.Persons.Include(p => p.Cars).Include(p => p.Pets).Include(p => p.Children).Where(p => p.Id == personId);

  • Explicit Loading by using the change tracker and Load method on your entry like this : db.entry(person).Collection(p => p.Cars).Load();

The solution that I see a lot with EF and Repository Pattern is to use a collection lambda expression as a parameter of your method like this :

public Person GetPerson(params Expression<Func<Person, object>>[] includes)
{
    using (var db = new DbContext())
    {
        IQueryable<Person> query = db.Posts;
        Array.ForEach(includes, expression => query = query.Include(expression));
        return query.FirstOrDefault();
    }
}

You use it like this : GetPerson(p => P.Cars, p => p.Pets, p => p.Children) With this solution you only load the navigational properties you need by specifing them as parameters of your method.

Upvotes: 1

Sentinel
Sentinel

Reputation: 3697

Explicitly call load method on your collection. This forces lazy load.

Upvotes: 0

Mark Shevchenko
Mark Shevchenko

Reputation: 8197

As far as I know there is not the single general solution.

So you can try these cases:

  1. Don't close read-only DbContext (just don't forget disable tracking). In some scenarios like web request you can create DbContext at the start of request, and dispose it and the end.

  2. Forget for memory demanding. If your plan to read 2Mb data from SQL, the something wrong with your design. 5Kb, 30Kb are not the big data.

  3. Think about cache. Let the necessary data will available always.

  4. Refactor your interfaces to load necessary data only. F.e. append methods LoadPersonsWithAddresses, LoadPersonsWithFamily, and so on.

Upvotes: 0

Igor Quirino
Igor Quirino

Reputation: 1195

You can use ajax to populate data on demand.

Like this:

https://cmatskas.com/update-an-mvc-partial-view-with-ajax/

Happy to help you!

Upvotes: 0

Related Questions