Reputation:
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
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
Reputation: 3697
Explicitly call load method on your collection. This forces lazy load.
Upvotes: 0
Reputation: 8197
As far as I know there is not the single general solution.
So you can try these cases:
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.
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.
Think about cache. Let the necessary data will available always.
Refactor your interfaces to load necessary data only. F.e. append methods LoadPersonsWithAddresses
, LoadPersonsWithFamily
, and so on.
Upvotes: 0
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