2014-10-30 54 views
1

当我使用用户管理填充自定义实体与ASP网标识(一到多)

private UserManager<MyUser> GetUserManager() 
{ 
    var userStore = new UserStore<MyUser>(_context); 
    return new UserManager<MyUser>(userStore); 
} 

public MyUser GetUser(string username) 
{ 
    return GetUserManager().FindByName(username); 
} 

我UserAddress实体加载用户,但我的地址类型和国家实体在UserAddress为null。

但是使用它来加载用户并填充所有实体。我在这里所做的只是访问这些实体,但不对它们做任何事情。

public MyUser GetUser(string username) 
{ 
    var addressTypes = _context.AddressType.ToList(); 
    var countries = _context.Countries.ToList();   
    return GetUserManager().FindByName(username); 
} 

还可以启用延迟加载,如下所示。

public MyUser GetUser(string username) 
    { 
     _context.Configuration.LazyLoadingEnabled = true; 
     var user = GetUserManager().FindByName(username); 
     _context.Configuration.LazyLoadingEnabled = false; 
     return user; 
    } 

那么,为什么是空的实体与延迟加载过,但他们的工作,如果我只是访问它们的背景下,却无可奈何他们?

我先使用DB。我的继承人实体(重要位)

public class MyUser : IdentityUser 
{ 
    public MyUser() 
    { 
     this.Address = new List<UserAddress>(); 
    } 

    public virtual IList<UserAddress> Address { get; set; } 
} 

[Table("AddressTypes")] 
public partial class AddressTypes 
{ 
    public AddressTypes() 
    { 
     this.Address = new List<UserAddress>(); 
    } 
    public int Id { get; set; } 
    public virtual IList<UserAddress> Address { get; set; } 
} 

[Table("Country")] 
public partial class Country 
{ 
    public Country() 
    { 
     this.Address = new List<UserAddress>(); 
    } 
    public int Id { get; set; } 
    public virtual IList<UserAddress> Address { get; set; } 
} 

[Table("UserAddress")] 
public partial class UserAddress 
{ 
    public int Id { get; set; } 
    public string UserId { get; set; } 
    public int AddressTypeId { get; set; } 
    public int CountryId { get; set; } 
    public AddressTypes AddressType { get; set; } 
    public Country Country { get; set; } 
    [ForeignKey("UserId")] 
    public MyUser User { get; set; } 
} 

回答

3

你有种在这里回答你自己的问题。 使用延迟加载时,在使用点符号访问数据库时,将重新查询数据库中的请求信息。因此,在您的示例中,访问user.AddressType实际上会向数据库发出另一个请求,以获取与该用户关联的AddressType并将其存储在上下文中。

当Lazy Loading关闭,并且您查询AddressTypes和Countries的数据库时,您将拉入DbContext,因此当您访问相关信息(例如user.AddressType)时,该用户的AddressType已被加载到DbContext中,所以它会使用它而不必重新查询数据库。无需预取它们,它们将始终为空。

如果您始终想要引入这些相关表格,那么您将需要修改查询以使用.Include()方法。为此,您将需要从UserStore派生并像这样覆盖FindByName方法。

public class MyUserStore : UserStore<MyUser> 
{ 
    public MyUserStore(DbContext context) : base(context) 
    { 
    } 

    public override MyUser FindByName(string userName) 
    { 
     return Users.Include(x=>x.AddressType).Include(x=>x.Country).FirstOrDefault(n=>n.UserName == userName); 
     //you may need to also include the following includes if you need them 
     //.Include(x=>x.Roles).Include(x=>x.Claims).Include(x=>x.Logins) 
    } 
} 

然后使用这个新的商店在你的UserManager

private MyUserManager GetUserManager() 
{ 
    var userStore = new MyUserStore(_context); 
    return new UserManager<MyUser>(userStore); 
} 
+1

我的实体框架延迟加载如何被关的理解。我认为即使没有抓取它们,它们也会被加载到上下文中,因为它们是相关的。谢谢你清理那个。 – garethb 2014-10-30 23:08:37