1

EF Core recently added explicitly load the navigation properties of an object;

using (var db = new BloggingContext()) {
    var blog = db.Blogs.Find(1);

    db.Entry(blog).Collection(b => b.Posts).Load();
    db.Entry(blog).Reference(b => b.Author).Load();
}

https://blogs.msdn.microsoft.com/dotnet/2016/11/16/announcing-entity-framework-core-1-1/

This is obviously verbose, and I don't wish to do these checks every time. Is there any extension methods or complementary NuGet packages available to get around these shortcomings?

I realise this is a common question, but not for EF Core.

EntityFramework Eager Load all Navigation Properties

Community
  • 1
  • 1
wonea
  • 4,783
  • 17
  • 86
  • 139
  • Does `.Include(..)` not work in core? ie. `db.Blogs.Include(m => m.Posts).Include(m => m.Author).Find(1);` – Rudi Visser Nov 24 '16 at 10:56
  • 1
    Yes, but I'm trying to get around explicitly specifying the entities I want. https://learn.microsoft.com/en-us/ef/core/querying/related-data – wonea Nov 24 '16 at 10:58
  • Ah, sorry, so your question is how to load all of the nav props off that model. I misread the title and tried to just make it simpler. I could think of a simple way to do it w/ Reflection, but not sure there's a built in method even for old EF. EDIT: Even the question you linked to would work for Core as you're still specifying what to load. EDIT2: I could be wrong, but I think `.Include(..)` is faster than loading individually too as they'll form part of the initial query run. – Rudi Visser Nov 24 '16 at 11:01
  • 1
    Loading them all this way is about the same as just using lazy loading (separate query would be made for each navigation property). So why do you want to do that? – Evk Nov 24 '16 at 11:09
  • @Evk Because EF Core currently does not support lazy loading? – Ivan Stoev Nov 24 '16 at 12:24
  • 1
    @IvanStoev I guess I'd better not commenting\answering EF Core questions any more, since even basic assumptions fail :) – Evk Nov 24 '16 at 12:29

2 Answers2

2

As mentioned in comments I'm fairly confident (though my usage of EF Core is limited) that this can't be done automatically through standard mapping of navigation properties. Also using .Load is less efficient (and much longer) than using .Include as you'll be running multiple queries just like using the lazy-loading navigation property itself.

There are 2 ways I can think of to approach the problem of not wishing to do the checks every time as per your question. The first would work for loading your Blog entity specifically, and the second that you could reuse across others but still requires changes to your loading.

1; Extension Method to load all related entities, something like this:

public static IQueryable<Blog> EagerWhere(this DbSet<Blogs> dbset, Expression<Func<Blog, bool>> expr) {
    return dbset
        .Include(m => m.Posts)
        .Include(m => m.Author)
        .Where(expr);
}

// .. usage

db.Blogs.EagerWhere(m => m.Id == 1);

(Note that I wrote this as EagerWhere so you have more control over the query so it's more reusable rather than a simple Find replacement)

2; Write a custom attribute, and write a method used similar to the above that performs the same action as .Find(..) but uses Reflection to find the properties with your custom attribute, and passes them into .Include(..) recursively.

I won't write an example for that as I'm not sure it's worth the effort due to the (normally) limited amount of entities created.

Rudi Visser
  • 21,350
  • 5
  • 71
  • 97
  • Afaik dotnet core does not support reflection propertyinfo yet. – alanh Nov 25 '16 at 17:43
  • @alanh Hmm, I thought it did. It's missing some things for sure, but nothing as critical as this. I can't say for sure though, I haven't had chance to get to grips with Core again since the RC2. – Rudi Visser Nov 29 '16 at 15:26
1

Now, in ef core5.0, you can use this code

//in OnModelCreating
modelBuilder.Entity<XXX>().Navigation(t => t.XX).AutoInclude();
Łukasz Sypniewski
  • 602
  • 1
  • 10
  • 19
SmRiley
  • 147
  • 1
  • 7
  • 1
    Please provide additional details in your answer. As it's currently written, it's hard to understand your solution. – Community Sep 06 '21 at 12:37
  • This is not available in EF Core 5. It is in EF Core 6. – johnye2e Dec 10 '21 at 14:13
  • If you're using the EF-Core scaffolding that overwrites the dbcontext everyone you re-generate you can create a partial class of the dbcontext and then put this in `partial void OnModelCreatingPartial(ModelBuilder builder)`. Works like a charm. – b.pell Oct 12 '22 at 16:27
  • @johnye2e ef core5 has documentation about it, though I'm not sure if it's available in 5 https://learn.microsoft.com/dotnet/api/microsoft.entityframeworkcore.metadata.builders.navigationbuilder.autoinclude?view=efcore-5.0 – SmRiley Oct 13 '22 at 01:14