2014-10-12 71 views
5

我有這個設置與代碼第一種模式:從IdentityUser訪問導航屬性時,惰性加載是關閉

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;} 
} 

我已經延長了IdentityUser包含「客戶」類的一個實例。

現在考慮下面的代碼:

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. 
} 

因爲延遲加載是關閉的,user.Customer爲空,因此給空引用異常。 如果有人能夠幫助我在LazyLoading關閉時訪問IdentityUser的導航屬性,我會很高興。

謝謝。

+0

配置是TestUser的和客戶之間的關係呢? – jd4u 2014-10-13 13:37:06

+0

我們是否需要這種關係的特殊配置?我很抱歉,但我不知道任何,請賜教。 – 2014-10-14 02:32:21

+0

回顧兩件事:1.DbContext的OnModelCreating方法&2. LazyLoadingEnabled:http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/reading-related-data-with- the-entity-framework-in-an-asp-net-mvc-application – jd4u 2014-10-14 11:39:09

回答

8

如果您總是希望在不使用延遲加載的情況下加載相關數據,那麼您需要編寫自己的UserStore實現並將其插入UserManager。例如..

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.. 
    } 
} 

那麼當您創建的UserManager,插件本實施UserStore的,和你的Customer數據將與用戶加載..這可能看起來像..

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

} 

取決於您的項目,UserManager實施將有所不同。

+1

你先生已經救了我一天。我意識到急切的加載不能用於IdentityDbContext,所以這是解決方法。 – hbulens 2015-09-08 13:44:14

4

我有這個解決:

創建自定義的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); 
    } 
} 

替換默認的UserManager服務

在你ConfigureServices補充一點:

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

爲DI

更改的參數從

[FromServices]UserManager<ApplicationUser> userManager 

[FromServices]ApplicationUserManager userManager 

我希望這有助於

+0

謝謝你一百萬!我幾乎都放棄了這樣做的方式,並打算做另一個數據庫調用來拉取必要的對象,因爲我能找到的所有解決方案都涉及覆蓋幾乎整個框架! – 2017-10-25 07:39:44