如何在 Where 部分的 IEnumerable 中设置参数

How to set parameter in IEnumerable in Where part

我不想知道 - 我可以在 IEnumerable 的 Where 部分传递特定参数吗? 例如我有这样的查询:

 IEnumerable<Bla> quer  = quer.Where(e => e.actual == 1 && param);

哪里param就会这样

 e.Number > 5 

我认为可以通过 IsNullOrEmpty 来完成,但也许可以使用泛型?
我使用 EF,它是 Web Forms。

 public class BLA
    {
        [Key]
        public int IDin { get; set; }
        public int actual { get; set; }
        public string code { get; set; }     
        public DateTime Date  { get; set; }

    }

任何 linq 中的参数 where 条件总是产生一个布尔值。 即 e.actual == 1 是布尔结果,要么为 true 要么为 flase。这样它将是一个参数,也需要布尔值。 var param = e.Number > 5 可以,但是 var param = "e.Number > 5" 不行。

如果你定义param为一个函数(准确的说是Func<Bla, bool>),你可以调用它:

Func<Bla, bool> param = bla => bla.Number > 5;

并调用它:

IEnumerable<Bla> quer  = quer.Where(e => e.actual == 1 && (param?.Invoke(e) ?? true));

?? true 允许您在 paramnull 时默认结果。如果 paramnull,现在它将 return true,但如果您愿意,可以更改它。

因为你是运行 EF,所以你不能用上面的方法。

您可以使用 Expression<Func<Bla, bool>>。 EF 可以将表达式翻译成实际的 SQL:

Expression<Func<Bla, bool>> param = bla => bla.Number > 5;

IEnumerable<Bla> quer  = quer.Where(e => e.actual == 1)
                             .Where(param);

对于更复杂的函数,您必须先具体化结果:

IEnumerable<Bla> quer  = quer.Where(e => e.actual == 1)
                             .ToList() // materialize
                             .Where(e => param?.Invoke(e) ?? true);

可以只在需要的时候应用第二个条件,像这样:

// Always apply first condition:
IEnumerable<Bla> query = quer.Where(e => e.actual == 1);

// When needed, also apply second condition:
int? valueToCheck = someValue; // or null
if (valueToCheck.HasValue)
{
    query = quer.Where(e.Number > valueToCheck.Value);
}

然而,如果您甚至需要改变 e.Number > 部分,那么这种方法就不会那么容易遵循。

它也可以像这样写得更短一点(也许更易读):

int? valueToCheck = someValue; // or null
IEnumerable<Bla> query = quer
    .Where(e => e.actual == 1);
    .Where(e => valueToCheck == null || e.Number > valueToCheck.Value);

您可以使用参数,并将其添加到查询中

Expression<Func<Bla, bool>> param = bla => bla.Number > 5;
IEnumerable<Bla> query = query.Where(e => e.actual == 1).Where(param);

因为是两次调用,如果第二次调用为null,可以省略。

public void SomeMethod(Expression<Func<Bla, bool>> param) {
    IEnumerable<Bla> query = quer.Where(e => e.actual == 1).Where(param);
    if (param != null) {
        query = query.Where(param);
    }
    // ...
}

// Usage
SomeMethod(null);
// or
SomeMethod(bla => bla.Number > 5);