7

I'm currently using Entity Framework to build a Forum using ASP.NET MVC I Have 3 principal Models [Category] 1--* [Forum] 1--* [Post]

If i Had 5 Categories and each one have 4 Forums and each Forum have 1000 post and I want to display only Categories, When I do that is that mean i have selected the 20000 posts too ??

Because each Category object have a List<'Forum'> and each Forum object have List<'Post'> due to mapping and relations

Nic
  • 12,220
  • 20
  • 77
  • 105
Charaf
  • 177
  • 1
  • 2
  • 12

4 Answers4

5

You can use lazy loading to prevent child objects from being retrieved. See here. Lazy loading should be enabled by default.

Lazy loading is the process whereby an entity or collection of entities is automatically loaded from the database the first time that a property referring to the entity/entities is accessed.

When using POCO entity types, lazy loading is achieved by creating instances of derived proxy types and then overriding virtual properties to add the loading hook. For example, when using the Blog entity class defined below, the related Posts will be loaded the first time the Posts navigation property is accessed:

public virtual ICollection<Post> Posts { get; set; } 

You can achieve specific eager loading by using .Include(). For example:

db.Forums.Include(i => i.Posts)
Nic
  • 12,220
  • 20
  • 77
  • 105
  • 1
    Thank you sir .. I have made the property Post **virtual** , so I think lazy loading is already enabled :) – Charaf Jul 17 '16 at 00:30
  • What about Entity Framework Core ! there's no such thing as Lazy Loading Currently! – Michał Ziobro May 08 '17 at 16:33
  • @MichałZiobro See this question http://stackoverflow.com/questions/40122162/entity-framework-core-lazy-loading – Nic May 08 '17 at 23:34
  • But here you are getting one person than explicitly you are doing second query for list of related items or one related item. But I have in the first query N items, Then looping N time to get related data makes N+1 problem – Michał Ziobro May 09 '17 at 07:39
  • I have seen some explicit querying like blogs = blogs.context.Blogs.ToLis() , then context.Posts.Where(p => p.blogs.in(blogs).toList(); and then I have this Posts added to ChangeTracker? and they been accessed but nothing more has been loaded. But maybe Entity Framework Core always loads (eagerly) related enities if it is principal entity and they are dependent entities? and is not loading from depentend it's principal? – Michał Ziobro May 09 '17 at 07:45
  • your replay helped me. tank you so much – Esi Jul 09 '17 at 14:18
  • if you return the object as a part of WCF or REST call the referenced entities will be loaded in the end with lazy loading true.. Microsoft must have made an extension `Exclude` as an opposite to `Include`.. – Boppity Bop Apr 08 '20 at 12:00
0

use stored SQL procedure to display only categories in question. I assume that this functionality will be frequently used, therefore will affect performance. SP are precompiled, execution plan is known, additionally you may add a select distinct categoryField from aFewTablesnJoins where someId=@parameter in your categories query - Less IO, admin is more happy about performance. Of course Lazy instantiation is always an option as said above.

PawelSz
  • 164
  • 6
0

Ok I found this example and it uses Explicit Loading and IN operator. The code looks like this:

(dependent entity, has FK TutorId )[Course] N ->-------- 1 [Tutor] (principal entity)

(dependent entity, has FK SubjectId) [Course] N ->----- 1 [Subject] (principal entity)

// get all courses 
IEnumerable<Course> courses = context.Courses.ToList(); 
// select tutor ids from courses (C# logic, without DB access)
IEnumerable<int> tutorIds = courses.Select(c => c.TutorId);
// select subject ids from courses (C# logic, without DB access)
IEnumerable<int> subjectIds = courses.Select(c => c.SubjectId); 

context.Tutors.Where( t => tutorIds.Contains(t.TutorId) ).Load();
context.Subjects.Where( s => subjectIds.Contains(s.SubjectId) ).Load();

It seems this should be working, but I need to test it and give you a hint if it worked for me or not.

Michał Ziobro
  • 10,759
  • 11
  • 88
  • 143
-1

Set lazyloading=false in dbcontext file.

Manfred Radlwimmer
  • 13,257
  • 13
  • 53
  • 62
NIts577
  • 420
  • 3
  • 13