【发布时间】:2011-04-10 14:38:03
【问题描述】:
这里是一些示例数据:
List<Book> books = new List<Book>()
{
new Book(){Title = "artemis fowl: the time paradox", Pages = 380},
new Book(){Title = "the lieutenant", Pages = 258},
new Book(){Title = "the wheel of time", Pages = 1032},
new Book(){Title = "ender's game", Pages = 404},
new Book(){Title = "the sphere", Pages = 657}
};
背景:
上面使用了 Book 类的简化版本。当然,它会包含许多字段。我的最终目标是允许用户执行“高级”搜索,允许用户指定 any 字段,并进一步允许用户使用布尔代数为特定字段指定关键字。
例如:在标题搜索文本框中:+ (cake | pastry) + ~demon
上面的意思是:找出所有书名中包含“the”字样的书,无论是“cake”还是“pastry”,但没有“demon”字样。
问题:
小步骤将导致最终解决方案。所以我最初有以下代码:
List<Func<Book, bool>> fs = new List<Func<Book, bool>>()
{
b => b.Title.Contains("me"),
b => b.Title.Contains("the")
};
var q2 = from b in books select b;
foreach (var f in fs)
q2 = q2.Where(f);
foreach (Book b in q2)
{
Console.WriteLine("Title:\t\t{0}\nPages:\t\t{1}\n",
b.Title, b.Pages);
}
上面的代码工作正常。它会查找标题中包含“the”和“me”的书籍。
第二阶段
现在上面的过滤器是 FuncBook, bool> 类型的。该类将是一个实体框架生成的类,我不想在我的 UI 层中使用,在该层中将输入搜索短语并生成搜索过滤器以传递给 BLL。
所以我有以下三种尝试:
var q = from b in books select b;
List<Func<string, bool>> filters = new List<Func<string, bool>>()
{
s => s.Contains("me"),
s => s.Contains("the"),
};
//This works...
for (int i = 0; i != filters.Count; ++i)
{
Func<string, bool> daF = filters[i];
q = q.Where(b => (daF(b.Title)));
}
//This produces an exception...
//Due to index in query?
// for (int i = 0; i != filters.Count; ++i)
// {
// q = q.Where(b => ((filters[i])(b.Title)));
// }
//This runs but doesn't produce the proper output
// foreach (Func<string, bool> filter in filters)
// q = q.Where(b => filter(b.Title));
foreach (Book b in q)
{
Console.WriteLine("Title:\t\t{0}\nPages:\t\t{1}\n",
b.Title, b.Pages);
}
第一个被注释掉的片段会触发一个索引器超出范围异常,指出 i 的值为 2。
第二个被注释掉的部分运行并产生输出,但它打印出 5 本书中的 4 本书......除了标题为“ender's game”的书外,所有这些都打印出来。这不对……
所以,阅读我的帖子,我发现我无法控制解释每一个小细节的坏习惯......
所以你去。请解释为什么不同的输出。而且我想您可能会暗示我当前的“解决方案”可能会有所改进。
【问题讨论】:
标签: c# linq enumeration