How to load navigation properties on an IdentityUser with UserManager
Update for .NET 6.0 with EF Core 6.0:
You can now configure the property to be automatically included on every query.
modelBuilder.Entity<MyUser>().Navigation(e => e.Address).AutoInclude();
For more info check out: https://docs.microsoft.com/en-us/ef/core/querying/related-data/eager#model-configuration-for-auto-including-navigations
The short answer: you can't. However, there's options:
Explicitly load the relation later:
await context.Entry(user).Reference(x => x.Address).LoadAsync();
This will require issuing an additional query of course, but you can continue to pull the user via
UserManager
.Just use the context. You don't have to use
UserManager
. It just makes some things a little simpler. You can always fallback to querying directly via the context:var user = context.Users.Include(x => x.Address).SingleOrDefaultAsync(x=> x.Id == User.Identity.GetUserId());
FWIW, you don't need virtual
on your navigation property. That's for lazy-loading, which EF Core currently does not support. (Though, EF Core 2.1, currently in preview, will actually support lazy-loading.) Regardless, lazy-loading is a bad idea more often than not, so you should still stick to either eagerly or explicitly loading your relationships.
Unfortunately, you have to either do it manually or create your own IUserStore<IdentityUser>
where you load related data in the FindByEmailAsync
method:
public class MyStore : IUserStore<IdentityUser>, // the rest of the interfaces
{
// ... implement the dozens of methods
public async Task<IdentityUser> FindByEmailAsync(string normalizedEmail, CancellationToken token)
{
return await context.Users
.Include(x => x.Address)
.SingleAsync(x => x.Email == normalizedEmail);
}
}
Of course, implementing the entire store just for this isn't the best option.
You can also query the store directly, though:
UserManager<IdentityUser> userManager; // DI injected
var user = await userManager.Users
.Include(x => x.Address)
.SingleAsync(x => x.NormalizedEmail == email);