Access navigation properties from IdentityUser when disabling LazyLoading

I have this setup with the first code model:

public class TestContext :IdentityDbContext<TestUser> { public TestContext() : base("TestConnection") { this.Configuration.LazyLoadingEnabled = false; } public DbSet<Customer> Customers{get;set;} } public class TestUser : IdentityUser { public virtual Customer Customer { get; set; } } public class Customer { public int Id { get; set; } public string FirstName { get; set; } public string LastName {get; set;} } 

I extended IdentityUser to contain an instance of the Client class.

Now consider this code:

 var user = UserManager.FindById("some id"); if (user != null) { string str=user.Customer.FirstName; //since lazy loading is off, user.Customer is null and hence gives null reference exception. } 

since lazy loading is off, user. The client is null and therefore gives an exception to exclude links. I will be glad if anyone can help me access the IdentityUser navigation properties when LazyLoading is off.

Thanks.

+5
source share
2 answers

If you always want to download related data without using Lazy Loading, you need to write your own UserStore implementation and connect it to your UserManager . For instance..

 public class ApplicationUserStore : UserStore<TestUser> { public ApplicationUserStore(TestContext context) : base(context) { } public override TestUser FindByIdAsync(string userId) { return Users.Include(c => c.Customer).FirstOrDefault(u => u.Id == userId); //you may want to chain in some other .Include()s like Roles, Claims, Logins etc.. } } 

then when you create your UserManager, connect this implementation to the UserStore , and your Customer data will be loaded by the user .. it may look something like this.

 public class TestUserManager : UserManager<TestUser> { public TestUserManager() : base(new ApplicationUserStore(new TestContext())) { } } 

depending on your project, the implementation of UserManager will be different.

+8
source

I decided with this:

Create Custom UserManager

 public class ApplicationUserManager : UserManager<ApplicationUser> { public ApplicationUserManager(IUserStore<ApplicationUser> store, IOptions<IdentityOptions> optionsAccessor, IPasswordHasher<ApplicationUser> passwordHasher, IEnumerable<IUserValidator<ApplicationUser>> userValidators, IEnumerable<IPasswordValidator<ApplicationUser>> passwordValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, IServiceProvider services, ILogger<UserManager<ApplicationUser>> logger, IHttpContextAccessor contextAccessor) : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger, contextAccessor) { } public override Task<ApplicationUser> FindByIdAsync(string userId) { return Users.Include(c => c.Esercizio).FirstOrDefaultAsync(u => u.Id == userId); } } , IOptions <IdentityOptions> optionsAccessor, IPasswordHasher <ApplicationUser> passwordHasher, IEnumerable <IUserValidator <ApplicationUser >> userValidators, IEnumerable <IPasswordValidator <ApplicationUser >> passwordValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, IServiceProvider services, ILogger < public class ApplicationUserManager : UserManager<ApplicationUser> { public ApplicationUserManager(IUserStore<ApplicationUser> store, IOptions<IdentityOptions> optionsAccessor, IPasswordHasher<ApplicationUser> passwordHasher, IEnumerable<IUserValidator<ApplicationUser>> userValidators, IEnumerable<IPasswordValidator<ApplicationUser>> passwordValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, IServiceProvider services, ILogger<UserManager<ApplicationUser>> logger, IHttpContextAccessor contextAccessor) : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger, contextAccessor) { } public override Task<ApplicationUser> FindByIdAsync(string userId) { return Users.Include(c => c.Esercizio).FirstOrDefaultAsync(u => u.Id == userId); } } 

Replace the default UserManager service

In ConfigureServices add the following:

 services.AddIdentity<ApplicationUser, IdentityRole>().AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders().AddUserManager<ApplicationUserManager>(); 

Change arguments for DI

from

 [FromServices]UserManager<ApplicationUser> userManager 

to

 [FromServices]ApplicationUserManager userManager 

I hope this helps

+4
source

Source: https://habr.com/ru/post/1204506/


All Articles