好的,所以我写了以下功能:
private IQueryable<LogEntry> SelectAll<T>(IEnumerable<LogEntry> logEntries, List<Expression<Func<LogEntry, bool>>> whereClause)
{
var selectAllQuery = from l in logEntries select l;
if (whereClause != null)
{
foreach (Expression<Func<LogEntry, bool>> whereStatement in whereClause)
{
selectAllQuery = selectAllQuery.Where(whereClause);
}
}
}
但它不会编译。当它尝试在“selectAllQuery”返回一些内容时会抛出错误,如下所示:
System.Collections.Generic.IEnumerable'不包含'Where'的定义和最佳扩展方法重载 System.Linq.Enumerable.Where(System.Collections.Generic.IEnumerable,System.Func)'有一些无效的参数
我已经尝试过这种方式,我能想到的每一种方式都无济于事。在上面的代码中,运行初始select语句将返回selectAllQuery
System.Linq.Enumerable.WhereSelectEnumerableIterator<LogEntry,LogEntry>
显然,我遗漏了一些关于LINQ的基本知识。但是什么?
干杯。
答案 0 :(得分:5)
问题是selectAllQuery
是IEnumerable<LogEntry>
,您需要它为IQueryable<LogEntry>
才能使用表达式树。尝试更改方法的第一行:
var selectAllQuery = logEntries.AsQueryable();
或者,在编辑谓词时将它们转换为委托形式:
foreach (Expression<Func<LogEntry, bool>> whereStatement in whereClause)
{
selectAllQuery = selectAllQuery.Where(whereStatement.Compile());
}
编辑:好的,问题不仅仅是因为Queryable
,而是因为你的命名。让我们看看这个foreach
声明:
foreach (Expression<Func<LogEntry, bool>> whereStatement in whereClause)
{
selectAllQuery = selectAllQuery.Where(whereClause);
}
你没有在循环体中的任何地方使用whereStatement
。您试图在每次迭代时使用整个子句列表调用Where
。这是更好的命名有用的地方。试试这个,例如:
private IQueryable<LogEntry> SelectAll<T>(IEnumerable<LogEntry> logEntries,
List<Expression<Func<LogEntry, bool>>> filters)
{
var selectAllQuery = logEntries.AsQueryable();
if (filters != null)
{
foreach (var filter in filters)
{
selectAllQuery = selectAllQuery.Where(filter);
}
}
return selectAllQuery;
}
因为参数现在是多元化的,所以{em>显然错误作为Where
方法的参数 - 而whereStatement
和whereClause
之间的区别是所有明显,因为前者是单数,后者是复数。
答案 1 :(得分:1)
有时这些错误可以通过简单的解决方案来解决,例如将System.Linq添加到项目中......并在类文件中引用它。非常难过VS IDE无法帮助我们解析作为重构菜单的一部分...