LINQ to SQL Where 子句可选条件

Posted

技术标签:

【中文标题】LINQ to SQL Where 子句可选条件【英文标题】:LINQ to SQL Where Clause Optional Criteria 【发布时间】:2009-03-10 21:50:08 【问题描述】:

我正在使用 LINQ to SQL 查询并遇到了一个问题,我有 4 个可选字段来过滤数据结果。通过可选,我的意思是可以选择输入或不输入值。具体来说,一些文本框可能有一个值或一个空字符串,还有一些下拉列表可能已经选择了一个值,也可能没有......

例如:

    using (TagsModelDataContext db = new TagsModelDataContext())
     
        var query = from tags in db.TagsHeaders
                    where tags.CST.Equals(this.SelectedCust.CustCode.ToUpper()) 
                    && Utility.GetDate(DateTime.Parse(this.txtOrderDateFrom.Text)) <= tags.ORDDTE
                    && Utility.GetDate(DateTime.Parse(this.txtOrderDateTo.Text)) >= tags.ORDDTE
                    select tags;
        this.Results = query.ToADOTable(rec => new object[]  query );
    

现在我需要添加以下字段/过滤器,但前提是它们由用户提供。

    产品编号 - 来自另一个可以连接到 TagsHeaders 的表。 采购订单号 - TagsHeaders 表中的一个字段。 订单号 - 类似于 PO #,只是不同的列。 产品状态 - 如果用户从下拉列表中选择了此项,则需要在此处应用所选值。

我已经有的查询很好用,但是要完成这个功能,需要能够在 where 子句中添加这 4 项,只是不知道如何!

【问题讨论】:

在这里查看 Roscoe,它可能已经回答了。http://***.com/questions/11194/conditional-linq-queries 【参考方案1】:

您可以对原始查询进行编码:

var query = from tags in db.TagsHeaders
                where tags.CST.Equals(this.SelectedCust.CustCode.ToUpper()) 
                && Utility.GetDate(DateTime.Parse(this.txtOrderDateFrom.Text)) <= tags.ORDDTE
                && Utility.GetDate(DateTime.Parse(this.txtOrderDateTo.Text)) >= tags.ORDDTE
                select tags;

然后根据一个条件,添加额外的 where 约束。

if(condition)
    query = query.Where(i => i.PONumber == "ABC"); 

我不确定如何使用查询语法对此进行编码,但 id 确实适用于 lambda。也适用于初始查询的查询语法和二级过滤器的 lambda。

您还可以包含我不久前编写的扩展方法(如下),以包含条件 where 语句。 (不适用于查询语法):

        var query = db.TagsHeaders
            .Where(tags => tags.CST.Equals(this.SelectedCust.CustCode.ToUpper()))
            .Where(tags => Utility.GetDate(DateTime.Parse(this.txtOrderDateFrom.Text)) <= tags.ORDDTE)
            .Where(tags => Utility.GetDate(DateTime.Parse(this.txtOrderDateTo.Text)) >= tags.ORDDTE)
            .WhereIf(condition1, tags => tags.PONumber == "ABC")
            .WhereIf(condition2, tags => tags.XYZ > 123);

扩展方法:

public static IQueryable<TSource> WhereIf<TSource>(
    this IQueryable<TSource> source, bool condition,
    Expression<Func<TSource, bool>> predicate)

    if (condition)
        return source.Where(predicate);
    else
        return source;

这是 IEnumerables 的相同扩展方法:

public static IEnumerable<TSource> WhereIf<TSource>(
    this IEnumerable<TSource> source, bool condition,
    Func<TSource, bool> predicate)

    if (condition)
        return source.Where(predicate);
    else
        return source;

【讨论】:

+1 确实清理了代码并更好地沟通 +10 非常感谢您的回答。正是我正在寻找的。非常感谢您抽出时间来做这件事。 Ryan,仍在 SJH / PeaceHealth 工作。热爱我的工作。伟大的人。你在FB吗?我们真的应该在别处进行这种对话。 arobinson / gmail。 @andleer,你真棒,你不知道你拯救了多少迷失的灵魂:) @Ryan,很高兴在这方面提供帮助。【参考方案2】:

只需要使用条件检查参数的存在。例如:

where (string.IsNullOrEmpty(ProductNumber) || ProductNumber == tags.productNumber)

这样,如果没有输入产品编号,该表达式将在所有情况下都返回 true,但如果输入了它,它只会在匹配时返回 true。

【讨论】:

+1 很好。我之前也曾想过类似的事情 +1 我试图找到一个优雅的解决方案来解决“条件位置”,在我的情况下,我有多个连接并从连接表返回记录。像魅力一样工作!【参考方案3】:

您可以使用 || 进行 OR。

看看这个帖子,因为它可能会给你一些很好的指导: C# LINQ equivalent of a somewhat complex SQL query

【讨论】:

以上是关于LINQ to SQL Where 子句可选条件的主要内容,如果未能解决你的问题,请参考以下文章

LINQ to SQL查询中的C#Dynamic WHERE子句

linq to sql select和where的区别

带有可选 Where 子句和 Sql Server CE 的 Linq

LINQ to SQL语句之Where

LINQ to SQL语句之Where(抄的好)

LINQ to Object - 如何为子组实现 WHERE 子句“如果至少有一个元素是”