开发者

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 that EntityCollection used for handling Links has property IsLoaded which is false (and cannot be modified except by calling Load).
  • Removing 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.
  • Somehow cheating EF by replacing 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;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜