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));
}
这是一个使用Entity Framework的ASP.NET MVC3项目。如何编写查询以便在运行时生成它?
答案 0 :(得分:3)
看看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页面(大约一半)。
希望这有帮助!