Problem by Lazy loading in entity framework
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 becaus开发者_如何学Ce 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);
}
}
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:
- Turning lazy loading off. The disadvantage is that you must turn lazy loading off for whole processing of categories. Because once you turn it on it will immediately reload
Links
during next access to the property. The reason is thatEntityCollection
used for handlingLinks
has propertyIsLoaded
which is false (and cannot be modified except by callingLoad
). - Removing
virtual
keyword fromLinks
collection. This will disallow wrapping onlyCategory
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. - Somehow cheating EF by replacing
EntityCollection
inLinks
property with another collection. This is not easy because you can't just assign new collection toLinks
- dynamic proxy will throwInvalidOperationException
. 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;
精彩评论