【问题标题】:How to make a dynamic LINQ query?如何进行动态 LINQ 查询?
【发布时间】:2015-12-28 04:33:40
【问题描述】:

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

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 生成查询?

【问题讨论】:

  • 为什么会有两个内连接?实体框架查询是“延迟”查询。在您开始询问结果之前,它们实际上不会运行。根据您的代码,查询将在IList&lt;User&gt; UserLst=query.ToList(); 触发
  • 你想要达到什么样的结果?并向我们​​展示您在分析器中看到了什么 sql。向我们展示您的实体类(角色和用户)及其 EF 映射。
  • 嗨,Krill,我很抱歉这个问题,你想让我编辑我的问题吗?
  • 嗨,vantian,我遇到了这个问题,有什么办法可以解决它。请告诉我。
  • 没有User.Roles 导航属性吗?如果没有,您应该创建它。

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


【解决方案1】:

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

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

【讨论】:

  • 您好,我无法编写此查询,因为在我的用户类中我没有角色对象,而我只有 RoleId 列
  • @GopinathNavannethan 我没有从User 类中得到Role。看看我的查询,我创建了新类new { User = qu, Role = role }
  • 您好,谢谢,让我试试这个 :-)
【解决方案2】:

可以使用 to 表达式 --> 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;
    }

【讨论】:

  • 谢谢让我试试这个:-)
猜你喜欢
  • 1970-01-01
  • 2020-06-01
  • 2013-01-11
  • 1970-01-01
  • 1970-01-01
  • 2016-10-16
  • 2011-06-13
  • 1970-01-01
  • 2010-11-24
相关资源
最近更新 更多