好的,所以我编写了以下函数:

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”处返回某些内容时会引发错误,如下所示:



我试过用我能想到的每一种方式都无济于事。在上面的代码中,运行初始 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 方法的参数看起来显然是错误的 - 而 whereStatementwhereClause 之间的区别根本不明显,因为前者是单数而后者是复数。

关于c# - 无法从泛型转换以获取 LINQ where 子句,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4429620/

10-11 18:14