如何进行动态LINQ查询?

时间:2015-12-28 04:33:40

标签: c# entity-framework linq entity-framework-6

用户和角色有两个表。我必须获取有关实体框架工作中的请求的数据。这是我的请求类

public class UserRequestDTO
{
    public Int64? RoleId {get;set;}
    public Int64? DepartmentId {get;set;}
}

这是我的数据访问层

public IList<User> GetUser(UserRequestDTO _oUserRequestDTO)
{
    ///This Implements the DbContext
    DataContext _odb=new DataContext();

    IQueryable<User> query=_odb.user.where(a=>a.IsDisable.equals(false));

    if(_oUserRequestDTO.RoleId.HasValue)
    {
        query=  from qu in query
                from role in _odb.Role.where(a=>a.Id.equals(qu.RoleId))
                Where role.Id.equals(RoleId)&& role.IsDisable.equals(false))
                Select qu;
    }

    if(_oUserRequestDTO.DepartmentId.HasValue)
    {
        query=  from qu in query
                from role in _odb.Role.where(a=>a.Id.equals(qu.RoleId))
                Where role.Department.Id.equals(DepartmentId)&& role.IsDisable.equals(false))
                Select qu;
    }
    IList<User> UserLst=query.ToList();
    return UserLst;
}

我检查在SQL Server 2014 Profiler中触发的查询。如果我在请求中使用RoleId或DepartmentId进行过滤,则查询中没有问题。但是,如果我同时使用RoleId和DepartmentId进行过滤。在Profiler中,我看到了两个内部联接。

如何将其组合成单个内部联接?

有没有办法了解如何通过Linq生成查询?

2 个答案:

答案 0 :(得分:0)

在一个变量中选择查询的公共部分:

public IList<User> GetUser(UserRequestDTO _oUserRequestDTO)
{
    DataContext _odb = new DataContext();

    var users =_odb.user.where(a=>a.IsDisable.equals(false));

    var query = from qu in users
                from role in _odb.Role.where(a=>a.Id.equals(qu.RoleId))
                select new { User = qu, Role = role };


    if(_oUserRequestDTO.RoleId.HasValue)
    {
        query = from o in query
                where o.Role.Id.equals(RoleId) && o.Role.IsDisable.equals(false))
                select o;
    }

    if(_oUserRequestDTO.DepartmentId.HasValue)
    {
        query = from o in query
                where o.Role.Department.Id.equals(DepartmentId) && o.Role.IsDisable.equals(false))
                select o;
    }
    return query.Select(o => o.User).ToList();
}

答案 1 :(得分:0)

您可以使用Expression - &gt; LINQ to Entities: Combining Predicates

 public IList<User> GetUser(UserRequestDTO _oUserRequestDTO)
    {
        ///This Implements the DbContext
        DataContext _odb=new DataContext();
    Expression<Func<User, bool>> expresionWhere =a=>a.IsDisable.equals(false);



        if(_oUserRequestDTO.RoleId.HasValue)
        {

Expression<Func<User, bool>> expresionRoleId = UserRequestDTO.RoleId =RoleId  && !Role.IsDisable);
                expresionWhere= PredicateBuilder.And(expresionWhere, expresionRoleId );
        }

        if(_oUserRequestDTO.DepartmentId.HasValue)
        {

Expression<Func<User, bool>> expresionDepartmentId = UserRequestDTO.DepartmentId=DepartmentId && !Role.IsDisable);
                expresionWhere= PredicateBuilder.And(expresionWhere, expresionDepartmentId );
        }


        IList<User> UserLst=odb.user.Include("UserRequestDTO").Where(expresionWhere).toList();
        return UserLst;
    }