Как использовать выражение с универсальным лямбда-выражением func в предложении linq where? - PullRequest
3 голосов
/ 21 октября 2011

Вот что у меня есть

private readonly Dictionary<Type, List<object>> _cache;

public IList<T> Get<T> (Expression<Func<T, bool>> criteria)
{
    return _cache[typeof(T)].Where (criteria);
}

Компилятор (справедливо) жалуется, что не может преобразовать объект в T.

Как мне оттуда идти?


Решение

return _cached[type].AsQueryable().Cast<T>().Where (criteria).ToList()

Идея состоит в том, чтобы иметь список как IQueryable, и тогда я мог бы читать ...

Ответы [ 5 ]

4 голосов
/ 21 октября 2011

Используйте .Cast<>() Метод расширения :

private readonly Dictionary<Type, List<object>> _cache;

public IList<T> Get<T> (Expression<Func<T, bool>> criteria)
{
    return _cache[typeof(T)].Cast<T>().Where (criteria).ToList();
}

Если вы не совсем уверены, что все элементы относятся к типу T, вы можете использовать.OfType<T>() вместо этого (который пропускает элементы, которые не могут быть приведены)

Редактировать Вам также необходимо использовать .OfType<T>(), когда T является типом значения (структура),

Редактировать Поскольку в вашем комментарии упоминается IQueryable, это может помочь:

return _cache[typeof(T)].AsQueryable().Cast<T>().Where (criteria).ToList();
1 голос
/ 21 октября 2011

Хорошо, исправили это:

return _cached[type].AsQueryable().Cast<T>().Where (criteria).ToList()

Идея состоит в том, чтобы иметь список как IQueryable, и тогда я мог бы читать ...

1 голос
/ 21 октября 2011
private readonly Dictionary<Type, List<object>> _cache;

public IList<T> Get<T> (Expression<Func<T, bool>> criteria)
{
    return _cache[typeof(T)].Cast<T>().Where(criteria).ToList();
}
0 голосов
/ 21 октября 2011

Вам действительно нужен аргумент для выражения>?Из этого не следует делать трюк:

private readonly Dictionary<Type, List<object>> _cache;

public IList<T> Get<T>(Func<T,bool> criteria)
{
    return _cache[typeof(T)].Cast<T>().Where(criteria).ToList();
}
0 голосов
/ 21 октября 2011

может создавать выражение динамически, а затем компилировать его - лучший вариант. Вот образец:

Expression<Func<TestClass, bool>> query = LambdaBuilder.BuildQuery(queryItems);
Func<TestClass, bool> compiledExpression = query.Compile();
var results = data.Where(compiledExpression);

Вы можете прочитать мою статью на ней

...