Reputation: 20156
I have two entities in 1:n relationship: Link, Category. At the first I get all categories and Links and put them to list. Next I fill the links of every category manually but category.Links.Add(link)
connect to db and get the link again and it cause double data in the result. I know this action is because of lazy loading. the lazy loading is true and I do not want to disable it. How can I fill links of every category manually without connecting to db again?
Please do not offer Eager loading or disabeling lazy load.
var categories = categoryRepository.GetCategories().ToList();
var allLinks = linkRepository.GetLinks().ToList();
foreach (var category in categories)
{
var links = allLinks.Where(l => l.CategoryID == category.CategoryID);
foreach (var link in links)
{
category.Links.Add(link);
}
}
Upvotes: 2
Views: 5011
Reputation: 364249
Even you mentioned that you don't want to turn off the lazy loading I insists you to do that because lazy loading will be triggered always when you access the navigation property first time. The only way to avoid this is:
Links
during next access to the property. The reason is that EntityCollection
used for handling Links
has property IsLoaded
which is false (and cannot be modified except by calling Load
).virtual
keyword from Links
collection. This will disallow wrapping only Category
by dynamic proxy and because of that it will not allow lazy loading. It will be even more interesting because the only needed code in your loading should be first two lines - links will be populated to categories automatically during second query execution. The problem here is that removing virtual keyword from auto generated entities is hard (it must be hard coded to T4 template) or you must use own entity.EntityCollection
in Links
property with another collection. This is not easy because you can't just assign new collection to Links
- dynamic proxy will throw InvalidOperationException
. You must create second partial part of your entity and add some code which will modify directly private field holding the collection (bypassing the property). Even such approach can have some bad consequences. Default code uses some fixups etc.Turning lazy loading off will not break your functionality - actually EF is doing this quite often internally. You just need to do:
context.ContextOptions.LazyLoadingEnabled = false;
Upvotes: 1