Linq - 在IQueryable表达式中从列表中排除用户 - 正确的方法是什么?

时间:2015-09-27 09:18:23

标签: c# entity-framework linq

为了简化一些事情,我为用户"管理"创建了一个基类。这与已提供的帐户管理不同。

这是我的基类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using Microsoft.AspNet.Identity.EntityFramework;

namespace ARSoftwareV2.UserLibrary
{
    // This is a base class for all user needs. If you want to implement your own set of checks,
    // you can simply inherit from this class and you get pretty much everything you need already set up.
    public class UserClassBase
    {
        private Models.ApplicationDbContext DefaultContextInstance;
        // We only want to show the "final results" here, not what should be hidden.
        protected Models.ApplicationDbContext CreateNewContext()
        {
            return new Models.ApplicationDbContext();
        }

        protected Models.ApplicationDbContext DefaultContext
        {
            get
            {
                if ( DefaultContextInstance == null)
                {
                    DefaultContextInstance = CreateNewContext();
                }
                return DefaultContextInstance;
            }
        }
        // This lists users based on a number of criteria.
        // Called without arguments, the query lists all users which are:
        // - Enabled
        // - Not deleted
        // - Not employees (this isn't done yet)
        public IQueryable<Models.ApplicationUser> GetUserListQuery(bool IncludeDisabled = false, bool IncludeDeleted = false,bool IncludeEmployees = false )
        {
            IQueryable<Models.ApplicationUser> result;
            using (DefaultContext)
            {
                IQueryable<Models.ApplicationUser> UserQueryIncludeAll = (from user in DefaultContext.Users select user);
                result = UserQueryIncludeAll;
                if (!(IncludeEmployees == true))
                {
                    // I need to make a join here to exclude employees by the user list.
                }
                if ((IncludeDisabled == false) && (IncludeDeleted == false))
                {
                    result.Where(u => u.Enabled == true && u.Deleted == false);
                }
                else if (IncludeDisabled == true)
                {
                    result.Where(u => u.Deleted == true);
                }
                else if (IncludeDeleted == true)
                {
                    result.Where(u => u.Enabled == true);
                }
            }
            return result;
        }

        public bool UserEmailExists( string EmailToCheck )
        {
            IQueryable<Models.ApplicationUser> Query = GetUserListQuery().Where(u => u.Email == EmailToCheck && u.Roles.Contains();
            IList<Models.ApplicationUser> resultList = Query.ToList<Models.ApplicationUser>();
            return (resultList.Count >0);
        }

        public Models.ApplicationUser FindUserByID( string ID)
        {
            IQueryable<Models.ApplicationUser> Query = GetUserListQuery().Where(u => u.Id == ID);
            Models.ApplicationUser result = Query.FirstOrDefault();
            return result;
        }

        public string[] UserRoles( string UserID )
        {
            Models.ApplicationUser User;
            User = FindUserByID(UserID);
            IList<string> result = new List<string>;
            foreach( var r in User.Roles )
            {
                result.Add(r.ToString());
            }
            return result.ToArray<string>();
        }
    }
}  

这背后的想法是我可以从注册/登录基础设施和网络服务中使用它 所以,我遇到的问题是 - 如果员工必须被排除在外 - 我需要一种方法来确定角色。我认为,这必须通过加入来完成。除非你知道更好的方法,当然:)

Sooo,我的问题是:排除具有员工角色的用户的最佳方式是什么?如果 - 我认为 - 那必须是一个联接,你能否建议一个适用于我的案例的语法?我用Google搜索,VS2015似乎打算用任何标记红色标记来标记:)

到目前为止,我尝试过以下方式:

if (!(IncludeEmployees == true))
                {
                    // I need to make a join here to exclude employees by the user list.
                    result.Join(DefaultContext.Roles, r => Roles, Users => Users, Users.ID = r.UserID);
                }  

我也尝试过这种方式:

if (!(IncludeEmployees == true))
                {
                    innerResult = (from u in UserQueryIncludeAll select u).Join(DefaultContext.Roles, r => Roles, u.Id = r.UserID);
                }

看一下类似的问题,有一个答案意味着我需要多个上下文才能做到这一点。那是对的吗?

你能指出我做错了什么吗?

1 个答案:

答案 0 :(得分:1)

使用导航属性而不是手动连接,例如

result = result.Where(user => !user.Roles.Any(role => role.Id == "Employee"));

顺便说一下,您的代码缺少上述result分配,因此根本不进行任何过滤。另一个错误的是using (DefaultContext)语句,因为您正在处理缓存的实例成员。整个过程可以像这样简化

public IQueryable<Models.ApplicationUser> GetUserListQuery(bool IncludeDisabled = false, bool IncludeDeleted = false, bool IncludeEmployees = false )
{
    IQueryable<Models.ApplicationUser> result = DefaultContext.Users;
    if (!IncludeDisabled)
        result = result.Where(user => user.Enabled);
    if (!IncludeDeleted)
        result = result.Where(user => !user.Deleted);
    if (!IncludeEmployees)
        result = result.Where(user => !user.Roles.Any(role => role.Id == "Employee"));
    return result;
}