Хорошо, во-первых, вы абсолютно не должны использовать код здесь .Он был написан обученными трюками-хомяками, которых научили не бросать, когда имеешь дело с этим кодом такого рода.
Вам следует абсолютно выбрать один из вариантов, о которых вы знаете:
- Используйте «временную» переменную (если вы можете статически напечатать эту переменную как
IEnumerable<T>
, тогда вам не нужен вызов AsEnumerable
- это не сработает, если у вас естьанонимный тип в качестве типа элемента курса) - Используйте скобки для вызова
AsEnumerable
- Используйте синтаксис "плавная" или "точечная нотация", чтобы сделать вызов
AsEnumerable
подходящим.
Однако вы можете сделать немного магии, используя способ перевода выражений запросов.Вам просто нужно сделать так, чтобы один из стандартных операторов запросов с представлением в выражениях запросов имел другой перевод.Простейший вариант здесь, вероятно, «Где».Просто напишите свой собственный метод расширения, взяв IQueryable<T>
и Func<T, SomeType>
, где SomeType
не bool
, и вы в отъезде.Вот пример, сначала сам взлом, а затем пример его использования ...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
public static class QueryHacks
{
public static readonly HackToken TransferToClient = HackToken.Instance;
public static IEnumerable<T> Where<T>(
this IQueryable<T> source,
Func<T, HackToken> ignored)
{
// Just like AsEnumerable... we're just changing the compile-time
// type, effectively.
return source;
}
// This class only really exists to make sure we don't *accidentally* use
// the hack above.
public class HackToken
{
internal static readonly HackToken Instance = new HackToken();
private HackToken() {}
}
}
public class Test
{
static void Main()
{
// Pretend this is really a db context or whatever
IQueryable<string> source = new string[0].AsQueryable();
var query = from x in source
where x.StartsWith("Foo") // Queryable.Where
where QueryHacks.TransferToClient
where x.GetHashCode() == 5 // Enumerable.Where
select x.Length;
}
}