在运行时循环遍历参数以生成LINQ

本文关键字:LINQ 参数 运行时 循环 遍历 | 更新日期: 2023-09-27 18:03:23

public class Command
{
    public int CommandId { get; set; }
    public string Title { get; set; }
    public virtual ICollection<CommandPart> CommandParts { get; set; }
}
public class CommandPart
{
    public int CommandPartID { get; set; }
    public string part { get; set; }
    public virtual ICollection<Command> command { get; set; }
}
public ViewResult Filter(string myString)
{
    var foo = myString.Split(Convert.ToChar("+"));
    var a = foo[0];
    var b = foo[1];
    var query =
    db.Commands.Where(
        c =>
        c.CommandParts.Any(p => p.part == a) 
        && (c.CommandParts.Any(p2 => p2.part == b))).ToList();
    return View(query.ToList());
}

当foo中恰好有两个项时,上面的查询正常工作。我希望能够循环foo来创建查询。这是我的尝试,但它不工作:

        var foo = myString.Split(Convert.ToChar("+"));
        IQueryable<Command> query = db.Commands;
        foreach (var keyword in foo)
        {
            query = query.Where(c => c.CommandParts.Any(p => p.part == keyword));
        }

这是一个ASP。NET mvc项目使用实体框架。如何编写查询以便在运行时生成?

在运行时循环遍历参数以生成LINQ

看看PredicateBuilder。它是一个小的助手类,封装了一些LINQ表达式,允许您动态构建Where谓词子句。你可以把AND和OR子句放在一起,并且嵌套得很深。

你可以这样做(伪代码):

var predicate = PredicateBuilder.True<Command>(); //use True for ANDs
foreach(var keyword in foo) {
  predicate = predicate.And(c => c.CommandParts.Any(p => p.part==keyword));
}
var results = db.Commands.Where(predicate);

我错过了你正在使用EF,所以你需要下载LINQKit(一个NuGet,你也可以下载),并使用它的"AsExandable"扩展。关于这一点,请参阅PredicateBuilder页面(大约在下面一半)。

希望这对你有帮助!