在登录时在用户上加载集合

时间:2014-02-21 20:20:26

标签: c# asp.net-mvc-5 asp.net-identity

好的,所以我定制了ApplicationUser,我需要在用户登录时加载一个集合,而我只想找到最好的方法。我已经查看了Web上的示例,但这些示例仅通过添加自定义属性(而不是集合)来自定义ApplicationUser。我需要加载一个IList<>当用户登录时。我看到了几种方法可以做到这一点,我想知道哪些会被认为是最好的"方式(我知道这有些主观,但我认为这是一个新的方面)。

无论如何,在AcccountController的Login方法中我们有:

    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
            var user = await UserManager.FindAsync(model.UserName, model.Password);
            if (user != null)
            {

                await SignInAsync(user, model.RememberMe);
            }
            else
            {
                ModelState.AddModelError("", "Invalid username or password.");
            }
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

我可以在await SigninAsync()之后添加一行来加载我的收藏,但这似乎很浪费,因为UserManager已经进入数据库了。我真正想要的是在向用户查询数据库时告诉用户管理员.Include()我的集合的一些方法。我所看到的是继承UserStore<ApplicationUser>并覆盖FindByNameAsync()调用的UserManager函数:

   public virtual Task<TUser> FindByNameAsync(string userName)
    {
        this.ThrowIfDisposed();
        IQueryable<TUser> entitySet = 
            from u in this._userStore.EntitySet
            where u.UserName.ToUpper() == userName.ToUpper()
            select u;
        return Task.FromResult<TUser>(entitySet.FirstOrDefault<TUser>());
    }

并覆盖我使用的自定义ApplicationUser并加载我的属性。这是应该这样做的方式,还是我忽略了AspNet.Identity某处可以更简单地处理这个问题的东西?


因此,我的脸很快就会爆炸,看起来你不会继承UserStore<TUser>并且可以访问你可能真正想要使用的任何覆盖其中一种方法,因为它只是internalprivate。没有复制和粘贴所有UserStore<TUser>并重新编写我想要的一种方法有什么建议吗?

1 个答案:

答案 0 :(得分:1)

以下是执行此操作的一种方法:

public class PatientPortalUserStore<TUser> : UserStore<TUser>
    where TUser : ApplicationUser
{

    public PatientPortalUserStore(DbContext context) : base(context)
    {
        this._userStore = new EntityStore<TUser>(context);
    }

    private EntityStore<TUser> _userStore;

    public override Task<TUser> FindByNameAsync(string userName)
    {
        //This is the important piece to loading your own collection on login
        IQueryable<TUser> entitySet =
            from u in this._userStore.EntitySet.Include(u=>u.MyCustomUserCollection)
            where u.UserName.ToUpper() == userName.ToUpper()
            select u;
        return Task.FromResult<TUser>(entitySet.FirstOrDefault<TUser>());
    }
}


//Had to define this because EntityStore used by UserStore<TUser> is internal
class EntityStore<TEntity>
    where TEntity : class
{
    public DbContext Context
    {
        get;
        private set;
    }

    public DbSet<TEntity> DbEntitySet
    {
        get;
        private set;
    }

    public IQueryable<TEntity> EntitySet
    {
        get
        {
            return this.DbEntitySet;
        }
    }

    public EntityStore(DbContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        this.Context = context;
        this.DbEntitySet = context.Set<TEntity>();
    }

    public void Create(TEntity entity)
    {
        this.DbEntitySet.Add(entity);
    }

    public void Delete(TEntity entity)
    {
        this.Context.Entry<TEntity>(entity).State = EntityState.Deleted;
    }

    public virtual Task<TEntity> GetByIdAsync(object id)
    {
        return this.DbEntitySet.FindAsync(new object[] { id });
    }
}