我正在尝试使用LinqPad构建基本的动态Linq查询。我的方法要求用户选择1 - 3个选项,然后根据输入动态构建查询。
public void FilteredPropertySearch()
{
bool addAnotherOption = true;
int option;
Dictionary<int, bool> parameters = new Dictionary<int, bool>();
var predicate = PredicateBuilder.False<ResidentialProperty>();
Console.WriteLine("Follow instructions to filter property search results");
do
{
// get user input
option = int.Parse(Console.ReadLine());
switch(option)
{
case 1:
parameters.Add(1, true);
break;
// more cases - when case 0 addAnotherOption = false, loop ends
default:
Console.WriteLine("That was not a valid option");
break;
}
}while(addAnotherOption == true);
foreach(KeyValuePair<int, bool> p in parameters)
{
if(p.Key == 1 && p.Value == true)
predicate = predicate.Or (c => c.HasBackGarden);
if(p.Key == 2 && p.Value == true)
predicate = predicate.Or (c => c.HasFrontGarden);
if(p.Key == 3 && p.Value == true)
predicate = predicate.Or (c => c.HasSecureParking);
}
ResidentialProperties.Where (predicate).Dump();
}
foreach
循环应根据用户的输入构建查询,但是,例如,当我将字典中的第一个值设为true并且不选择其他值时,它不会返回任何结果。我肯定应该知道我的数据库表中有一些值满足Key(1)
为真的值。
我应该在query
if
后foreach
之后使用predicate.Or
做其他事吗?
编辑
我已经使用了谓词构建器,当我使用predicate.Or
时(根据编辑的代码),它似乎是(有点)工作,但它只返回我选择的第一个选项,它不是构建的表达树。我认为将predicate.And
更改为{{1}}会将每个选定的用户输入添加到过滤器表达式。
如果用户选择了所有三个选项,我只希望返回列HasBackGarden,HasFrontGarden和HasSecureParking为真的行。我该如何做到这一点?
答案 0 :(得分:3)
如果您想将结果集限制为满足所有条件的记录,那么您应该使用.And
代替.Or
,但是为此,您需要从PredicateBuilder.True<ResidentialProperty>()
开始,而不是False
。
这是因为在添加任何过滤器之前,正确的结果集包含所有记录,并且每个后续过滤器都会限制结果集。如果从False
开始,则所有记录都不可能满足谓词。
答案 1 :(得分:1)
从您的代码中看起来您正在使用var&#34;查询&#34;这是一个空的可枚举。请记住,您所谓的查询是数据集,Where语句是该数据集的查询。所以第一个查询是在一个空数据集上,看起来来自foreach的其他查询只会改进那个空集。
另外,你可以这样做。所以(q =&gt; q.HasWhatever)因为那些是bool。