【问题标题】:Ignoring null parameter in where clause linq to sql忽略where子句linq to sql中的空参数
【发布时间】:2020-12-28 14:45:42
【问题描述】:

我需要忽略 where 子句中的空参数,以便我可以从用户端使用应用的过滤器获取适当的数据。为了实现这一点,我目前正在使用 if..else 嵌套方法,该方法随着参数数量的增加而增大。我想知道是否有任何其他有效的方法可以通过避免行数和复杂性并提高可读性来处理这种情况

public List<Members> GetMembers(int currentPosition, string memberStatus,
                string package, string packageStatus, string branch)
{
    var members = new List<Members>();
    if (package != null)
    {
        //include package
        if (packageStatus != null)
        {
            //include package, packageStatus
            if (branch != null)
            {
                //include package,packageStatus,branch
                members = db.Members.Where(x => x.PackageName == package && x.PackageStatus == packageStatus && x.Branch == branch).ToList();
            }
            else
            {
                //include package,packageStatus
                members = db.Members.Where(x => x.PackageName == package && x.PackageStatus == packageStatus).ToList();
            }
        }
        else
        {
            if (branch != null)
            {
                //include package,branch
                members = db.Members.Where(x => x.PackageName == package && x.Branch == branch).ToList();
            }
            else
            {
                //include package
                members = db.Members.Where(x => x.PackageName == package).ToList();
            }
        }
    }
    else
    {
        if (packageStatus != null)
        {
            //include packageStatus
            if (branch != null)
            {
                //include packageStatus,branch
                members = db.Members.Where(x => x.PackageStatus == packageStatus && x.Branch == branch).ToList();
            }
            else
            {
                //include packageStatus
                members = db.Members.Where(x => x.PackageStatus == packageStatus).ToList();
            }
        }
        else
        {
            if (branch != null)
            {
                //include packageStatus,branch
                members = db.Members.Where(x => x.PackageStatus == packageStatus && x.Branch == branch).ToList();
            }
            else
            {
                //include nothing
                members = db.Members.ToList();
            }
        }
    }

    return members;
}

【问题讨论】:

  • package为空时你执行x =&gt; x.PackageName == package很奇怪。
  • @RomanRyzhiy 看到这就是问题所在。对这些参数感到困惑。抱歉现在将编辑代码

标签: c# code-readability maintainability


【解决方案1】:

您可以将这些条件添加到查询中。它不会产生最可读的 SQL,但假设您发现可读代码更重要并信任 SQL Server 的优化器:

members = db.Members.Where(x =>
    (package == null || x.PackageName == package) &&
    (packageStatus == null || x.PackageStatus == packageStatus) &&
    (branch == null || x.Branch == branch)
).ToList();
        

或者,您可以有条件地将Where()s 附加到IQueryable&lt;Member&gt; 类型的变量。参见例如entity framework: conditional filter

【讨论】:

    【解决方案2】:

    我想推荐一个可读版本的方法:

    public List<Members> GetMembers(int currentPosition, string memberStatus,
        string package, string packageStatus, string branch)
    {
        var members = new List<Members>();
    
        members = db.Members.ToList();
    
        if (package != null)
        {
            members = members.Where(x => x.PackageName == package);
        }
    
        if (packageStatus != null)
        {
            members = members.Where(x => x.PackageStatus == packageStatus);
        }
    
        if (branch != null)
        {
            members = members.Where(x => x.Branch == branch);
        }
    
        return members.ToList();
    }
    

    【讨论】:

    • 这不会编译,Where 不会返回列表。
    • 我的意思是你的members = members.Where()members 变量的类型为 List&lt;Member&gt;,您不能为其分配 IQueryable&lt;Member&gt;
    • 我试过这个。但问题是因为我使用分页并且每次返回 10 行。我只需要从 db 中选择 10 行,过滤它们后,行会减少更多。所以我不能从数据库中选择所有成员。但如果取 10 并过滤,我将返回少于 10 个成员。无论如何感谢您的回答
    • @Thameem 然后添加.Take(10) 喜欢这里stackoverflow.com/questions/2656576/…
    【解决方案3】:

    我认为这行得通(还没有尝试编译它,但在我的脑海中它是有道理的)

        public List<Members> GetMembers(int currentPosition, string memberStatus,
                    string package, string packageStatus, string branch)
        {
            List<Members> ret = db.Members()
            if(memberStatus != null || package != null || packageStatus != null || branch != null)
            {
                ret = db.Members.Where(x => 
                    (memberStatus == null) ? (true) : (memberStatus == x.MemberStatus)
                    && (package == null) ? (true) : (package == x.PackageName)
                    && (packageStatus == null) ? (true) : (packageStatus == x.PackageStatus)
                    && (branch == null) ? (true) : (branch == x.Branch)
                ).ToList();
            }
            return ret;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-24
      • 1970-01-01
      • 2017-05-31
      • 2015-08-29
      • 1970-01-01
      • 2011-01-25
      相关资源
      最近更新 更多