开发者

Cannot cast from generic to get LINQ where clause

OK so I've written the following function:

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);
        }
    }
}

But it won't compil开发者_运维技巧e. It throws an error when it tries to return something at "selectAllQuery" as follows:

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

I've tried casting this every which way I can think of to no avail. In the above code, running the initial select statement returns selectAllQuery of type System.Linq.Enumerable.WhereSelectEnumerableIterator<LogEntry,LogEntry>

Clearly I'm missing something fundamental about LINQ. But what?

Cheers.


The problem is that selectAllQuery is an IEnumerable<LogEntry> and you need it to be an IQueryable<LogEntry> in order to use expression trees. Try just changing the first line of the method:

var selectAllQuery = logEntries.AsQueryable();

Alternatively, compile the predicates as you go to get them into delegate form:

foreach (Expression<Func<LogEntry, bool>> whereStatement in whereClause)
{
    selectAllQuery = selectAllQuery.Where(whereStatement.Compile());
}

EDIT: Okay, the problems weren't just because of Queryable, but because of your naming. Let's look at this foreach statement:

foreach (Expression<Func<LogEntry, bool>> whereStatement in whereClause)
{
    selectAllQuery = selectAllQuery.Where(whereClause);
}

You're not using whereStatement anywhere in the body of the loop. You're trying to call Where with the entire list of clauses on each iteration. This is where better naming would help. Try this, for example:

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;
}

Because the parameter is now pluralized, it would look obviously wrong as the argument to the Where method - whereas the difference between whereStatement and whereClause isn't at all obvious as the former being singular and the latter being plural.


Some times these kind of errors would get away with simple solution like adding System.Linq to the project...and referring it in the class file. Very sad that VS IDE does not help us to resolve as part of the refactor menu...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜