好的,我编写了以下函数:
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' does not contain a definition for 'Where' and the best extension method overload System.Linq.Enumerable.Where(System.Collections.Generic.IEnumerable, System.Func)' has some invalid arguments
我已经尝试过各种我能想到的方式来转换它,但没有成功。在上面的代码中,运行初始 select 语句返回 selectAllQuery
类型 System.Linq.Enumerable.WhereSelectEnumerableIterator<LogEntry,LogEntry>
显然我错过了有关 LINQ 的一些基本知识。但什么?
干杯。
最佳答案
问题是 selectAllQuery
是 IEnumerable<LogEntry>
你需要它是 IQueryable<LogEntry>
为了使用表达式树。尝试仅更改方法的第一行:
var selectAllQuery = logEntries.AsQueryable();
或者,编译谓词以将它们转换为委托(delegate)形式:
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;
}
因为参数现在是复数形式,所以作为 Where
的参数,它看起来显然是错误的。方法 - 而 whereStatement
之间的区别和whereClause
根本不明显,因为前者是单数,后者是复数。
关于c# - 无法从泛型强制转换以获取 LINQ where 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4429620/