0

我想有 3-4 个搜索选项。现在我在 If 语句中使用我的查询。

     if inputcol1 > 0 And Not inputCol2 = "" then 
         Dim list = (From P In db.table
                     Where P.column1 = inputCol1 and P.column2 = inputCol2
                     Select P).ToList()
     end if

还有一个(或 4 个)具有另一个条件但几乎相同的查询,只有一个不同的 where 子句。所以这个查询是简化和简短的。因此,如果我有一个非常大的查询,那将是一团糟。而且我不希望其他程序员只为几个选项阅读这么多代码。

是否有一种适当的简单方法来查看搜索选项是否已填写并进行查询?

4

4 回答 4

1

现在已经很晚了,但我目前正在研究一个 VB.NET 项目,除了 Gert Arnold 的回答之外,选择相同的对象也很重要。P 链接时,因为例如说 P 是项目实体,并且在您的最终结果中(过滤后)您正在选择其他列或对象详细信息,例如query = (From P in query Select P.Name, P.Deadline),它将引发转换异常,因为该变量querySelect P.Name, P.Deadline. 因此,如果您想在最终选择中使用不同的结构,请使用另一个变量,例如:

Dim query = (From P in query Where P.Col2 = inputCol2 Select P)
Dim result = From P In query Select P.Name, P.Deadline ... 
'and then displaying it 
DataGridView.DataSource = result.toList()

但是,我确实尝试过创建一个新类型,result = From P in query Select New With {P.Name, P.Deadline}但它没有用。不知道为什么,有空就去研究一下。

于 2018-12-13T20:35:24.137 回答
0

您可能喜欢尝试LinqKit。有了这个库,你就有了一个PredicateBuilder带有方法的类:

public static Expression<Func<T, bool>> True<T>();
public static Expression<Func<T, bool>> False<T>();
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2);
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2);

这些是Expression对象的扩展,可以从 lambda 轻松创建。

有了这样的表情你就可以做到yourDataSource.Where(expression)

对不起 c# 符号,我不知道 VB.net ...如果有人想将它修复到 VB,请随意。

编辑:

好吧,PredicateBuilder只是一个简洁的语法糖。在他们的网站上,您可以找到非常简单的完整源代码。不幸的是,在 C# 中。它是这样的:

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;

public static class PredicateBuilder
{
  public static Expression<Func<T, bool>> True<T> ()  { return f => true;  }
  public static Expression<Func<T, bool>> False<T> () { return f => false; }

  public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1,
                                                      Expression<Func<T, bool>> expr2)
  {
    var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
    return Expression.Lambda<Func<T, bool>>
          (Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters);
  }

  public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
                                                       Expression<Func<T, bool>> expr2)
  {
    var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
    return Expression.Lambda<Func<T, bool>>
          (Expression.AndAlso (expr1.Body, invokedExpr), expr1.Parameters);
  }
}

就是这样!表达式(在 .net 中是标准的,不需要额外的库)提供了一些很好的方法来处理它们,它们可以在where子句中使用。试试看 :)

于 2012-09-26T09:15:16.337 回答
0

您的代码走在了正确的轨道上。您只需要更改三元运算符的 if 语句:

    Dim table = New Dictionary(Of Integer, String)
    table.Add(1, "one")
    table.Add(2, "two")
    table.Add(3, "three")

    Dim inputCol1 As Integer
    Dim inputCol2 As String = "one"

    Dim list = (From P In table Where _
                (inputCol1 < 1 OrElse P.Key = inputCol1) _
                And (inputCol2 = "" OrElse P.Value = inputCol2) _
                Select P).ToList()

在此问题上查找有关此情况的更多信息:条件过滤

于 2012-09-26T10:53:05.900 回答
0

最好的方法是有条件地扩展您的查询:

Dim query = (From P In db.table Select P)

If inputCol1.HasValue
    query = (From P in query Where P.column1 = inputCol1 Select P)
End If
If inputCol2.HasValue
    query = (From P in query Where P.inputCol2 = inputCol2 Select P)
End If
' And so on...

Dim list = query.ToList()

条件过滤 withNot inputCol2.HasValue OrElse P.Value = inputCol2将创建一个带有无用谓词的查询。通过有条件地扩展您的查询,只会合并重要的谓词。

于 2012-09-26T11:45:57.610 回答