与ASP网标识(一到多)自定义实体 [英] Custom entities with asp net identity (one-to-many)

查看:148
本文介绍了与ASP网标识(一到多)自定义实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我使用用户管理器加载用户

 私人的UserManager<&MYUSER GT; GetUserManager()
{
变种userStore =新UserStore<&MYUSER GT;(_背景);
返回新的UserManager<&MYUSER GT;(userStore);
}

公共MYUSER的getUser(用户名字符串)
{
返回GetUserManager()FindByName(用户名)。
}



我UserAddress实体填充,但在UserAddress我的地址类型和国家的实体是空值。



不过以此来加载用户,并填充所有实体。我要做的一切就是在这里访问的实体,但不跟他们什么。

 公共MYUSER的getUser(用户名字符串)
{
VAR addressTypes = _context.AddressType.ToList();
变种国家= _context.Countries.ToList();
返回GetUserManager()FindByName(用户名);
}



也使得延迟加载就像下面。

 公共MYUSER的getUser(用户名字符串)
{
_context.Configuration.LazyLoadingEnabled = TRUE;
VAR用户= GetUserManager()FindByName(用户名)。
_context.Configuration.LazyLoadingEnabled = FALSE;
回报用户;
}



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



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

 公共类MYUSER:IdentityUser 
{
公共MYUSER()
{
this.Address =新的List< UserAddress>();
}

公共虚拟的IList< UserAddress>地址{搞定;组; }
}

表(AddressTypes)]
公共部分类AddressTypes
{
公共AddressTypes()
{
this.Address =新的List< UserAddress>();
}
公众诠释标识{搞定;组; }
公共虚拟的IList< UserAddress>地址{搞定;组; }
}

表(国家)]
公共部分类国家
{
公国()
{
this.Address =新的List< UserAddress>();
}
公众诠释标识{搞定;组; }
公共虚拟的IList< UserAddress>地址{搞定;组; }
}

表(UserAddress)]
公共部分类UserAddress
{
公众诠释标识{搞定;组; }
公共字符串userid {搞定;组; }
公众诠释AddressTypeId {搞定;组; }
公众诠释CountryId {搞定;组; }
公共AddressTypes地址类型{搞定;组; }
公国国家{搞定;组; }
[ForeignKey的(用户ID)]
公共MYUSER用户{搞定;组; }
}


解决方案

您已经种在这里回答你自己的问题。
采用延迟加载,数据库被重新查询,因为当你使用点符号访问它所需的信息。所以,在你的榜样访问 user.AddressType 实际上使另一个请求到数据库获得相关的给该用户的地址类型,并将其存储在语境。



通过延迟加载关闭,您查询DB的AddressTypes和国家,你是拉再进入的DbContext所以当你访问即相关信息 user.AddressType ,该用户的地址类型已经被加载到的DbContext,因此它会使用,而不必重新查询数据库。不预取他们,他们将永远是空的。



如果你总是想在那些相关的表带上,那么你将需要修改您的查询使用 .INCLUDE()方法。对于这一点,你将需要UserStore派生并重写,像这样的FindByName方法

 公共类MyUserStore:UserStore< MYUSER> 
{
公共MyUserStore(的DbContext上下文):基地(上下文)
{
}

公众覆盖MYUSER FindByName(用户名字符串)
{
返回Users.Include(X => x.AddressType).INCLUDE(X => x.Country).FirstOrDefault(N => n.UserName ==用户名);
//你可能还需要包括以下内容包括如果需要的话
//包括(X => x.Roles)。.INCLUDE(X => x.Claims).INCLUDE( X => x.Logins)
}
}

然后使用此在你的UserManager新店

 私人MyUserManager GetUserManager()
{
变种userStore =新MyUserStore(_context );
返回新的UserManager<&MYUSER GT;(userStore);
}


When I load a user using the User Manager

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

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

my UserAddress entity is populated, but my AddressType and Country entities in the UserAddress is null.

However using this to load a user and all entities are populated. All I do here is access the entities but don't do anything with them.

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

Also enabling lazy loading works like below.

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

So why are the entities null with lazy loading off but they work if I just access them in the context but do nothing with them?

I'm using DB First. Heres my entities (the important bits)

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

解决方案

You've kind of answered your own Question here. With Lazy Loading, the database is re-queried for the requested information when you access it using the dot notation. So in your example accessing user.AddressType would actually make another request to the DB to get the AddressType associated to that user and store it in the Context.

With Lazy Loading turned off, and you querying the DB for the AddressTypes and Countries, you are pulling then into the DbContext so when you access the related information i.e.user.AddressType, the AddressType for that user is already loaded into the DbContext, so it will use that and not have to requery the database. without prefetching them, they will always be a null.

If you always want to bring in those related tables, then you will need to modify your query to use the .Include() method. For this you will need to derive from UserStore and override the FindByName method like so.

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

then use this new Store in your UserManager

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

这篇关于与ASP网标识(一到多)自定义实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆