你不有做到这一点使用动态查询语法,但你可以。
你真的有两个查询发生,所以你应该建立它们。你可以一次完成所有事情,但是你需要两种不同的地方条款,一种是流派,一种是标题。考虑下面的例子,模仿你的情况。
class Foo
{
public int Id { get; set; }
public string Name { get; set; }
public List<Bar> Bars { get; set; }
}
class Bar
{
public string Color { get; set; }
}
...
List<Foo> foos = new List<Foo>()
{
new Foo() { Id = 1, Name = "Apple", Bars = new List<Bar>() { new Bar() { Color = "Red"}, new Bar() { Color="Green"}} },
new Foo() { Id = 2, Name = "Orange", Bars = new List<Bar>() { new Bar() { Color = "Orange"},new Bar() { Color="Red Orange"}} },
new Foo() { Id = 3, Name = "Banana",Bars = new List<Bar>() { new Bar() { Color = "Yellow"},new Bar() { Color="Green"}} },
new Foo() { Id = 4, Name = "Pear",Bars = new List<Bar>() { new Bar() { Color = "Green"},new Bar() { Color="Yellow"}} }
};
string fooName = "Apple";
string barColor = "Green";
var fooQuery = foos.AsQueryable();
if (!string.IsNullOrEmpty(fooName))
{
string filter = string.Format("Name = \"{0}\"", fooName);
fooQuery = fooQuery.Where(filter);
}
var barQuery = fooQuery.SelectMany(f => f.Bars);
if (!string.IsNullOrEmpty(barColor))
{
string filter = string.Format("Color = \"{0}\"", barColor);
barQuery = barQuery.Where(filter);
}
的第一件事是,它建立了一个FOOS查询。如果它需要过滤(基于fooSearchName变量),它会生成一个Where子句并将其添加到查询中。之后,它成为返回Bar元素的查询的基础。同样的事情,如果它需要过滤,则会生成一个Where子句并将其添加到查询中。
不幸的是,由于在第一步中正在评估类型推断,所以无法在步骤上构建一个单个查询。如果您要说var query = foos.AsQueryable();
,则查询已经评估为IQueryable<Foo>
,因此在稍后的语句中添加SelectMany以选择条失败,因为这要求查询为IQueryable<Bar>
。
在这样的情况下,你的手是被迫的,你必须一次构建查询,或者至少到SelectMany的部分,最后的where子句可以在后面添加。所以你可以做到这一点:
var query = foos.AsQueryable().Where(fooSearchClause).SelectMany(f => f.Bars);
// later
query = query.Where(barSearchClause);
或者你构建查询为一个使用另一个,如我的示例所示。
无论如何,使用我提供的术语,遍历最终查询会得到一个结果。更改任一搜索变量的内容都会导致查询产生不同的结果。
Anthony ...这是我最终做的....感谢您的帮助 IQueryable