使用linq-to-sql帮助进行高级数据库搜索

Dar*_*rcy 2 c# asp.net-mvc for-loop linq-to-sql

我有一个包含"命令"和"状态"的数据库表.每个命令可以有多个状态,用户可以在搜索时配置它.例如,命令可以是"运行",它可以有两种状态:"快速"和"慢速".

我想在我的表中搜索所有名为"Run"的命令,其中包含"Fast"或"Slow".这很简单:

var results = from t in table
              where t.Command == "Run" &&
              (t.State == "Fast" || t.State == "Slow")
              return t;
Run Code Online (Sandbox Code Playgroud)

但是,用户还可以使用状态"快速"搜索命令"Walk",因此查询将如下所示:

    var results = from t in table
                  where (t.Command == "Run" &&
                        (t.State == "Fast" || t.State == "Slow")) ||
                  (t.Command == "Walk" &&
                   t.State == "Fast")
                  return t;
Run Code Online (Sandbox Code Playgroud)

像这样有很多搜索的潜力,我想知道如何将它们组合在一个循环中.

我不能这样做:

foreach(var command in commands)
{
    foreach(var state in command.states)
    {
        results = from t in table
                  where t.Command == command.Command &&
                  t.State == state;
    }
}
Run Code Online (Sandbox Code Playgroud)

因为一旦它搜索"运行","行走"将被排除在结果之外,因此要求"行走"将导致根本没有结果.

有谁知道这样做的好方法?

Str*_*ior 7

使用Joe Albahari的PredicateBuilder构建谓词:

var predicate = PredicateBuilder.False<Entry>();
foreach(var command in commands)
{
    foreach(var state in command.states)
    {
        predicate = predicate.Or(p => p.Command == command.Command && p.State == state);
    }
}
var query = table.Where(predicate);
Run Code Online (Sandbox Code Playgroud)

或者更LINQ重的版本:

var commandStates = from c in commands
                    from s in c.states
                    select new {c.Command, State = s};
var predicate = commandStates.Aggregate(
    PredicateBuilder.False<Entry>(),
    (pred, e) => pred.Or(p => p.Command == e.Command && p.State == e.state));
var query = table.Where(predicate);
Run Code Online (Sandbox Code Playgroud)