Инкапсуляция оператора выбора LINQ

У меня есть заявление LINQ, которое выглядит так:

return ( from c in customers select new ClientEntity() { Name = c.Name, ... });

Я хотел бы иметь возможность абстрагировать select в его собственный метод, чтобы у меня была другая опция «mapping». Что должен вернуть мой метод?

По сути, я бы хотел, чтобы мой запрос LINQ выглядел так:

return ( from c in customers select new Mapper(c));

Редактировать:

Это для LINQ to SQL.

10.12.2008 18:18:36
4 ОТВЕТА
РЕШЕНИЕ

Новый ответ теперь я заметил, что это Linq to SQL ... :)

Если вы посмотрите на версию Select, которая работает, IQueryable<T>она не займет Func<In, Out>. Вместо этого требуется Expression<Func<In, Out>>. Компилятор знает, как создать такую ​​вещь из лямбды, поэтому ваш обычный код компилируется.

Таким образом, чтобы иметь множество готовых к использованию функций отображения отображения, передав их в Select, вы можете объявить их следующим образом:

private static readonly Expression<Func<CustomerInfo, string>> GetName = c => c.Name;

private static readonly Expression<Func<CustomerInfo, ClientEntity>> GetEntity = c => new ClientEntity { Name = c.Name, ... };

Затем вы бы использовали их так:

var names = customers.Select(GetName);

var entities = customers.Select(GetEntity);
4
10.12.2008 20:05:43
После привязки вашего решения и bdukes я должен сказать, что ваше решение лучше, так как оно может анализировать выражение и фактически создавать из него SQL. bdukes 'принес все результаты и затем применил другие пункты в памяти.
Esteban Araya 10.12.2008 23:15:22

Это для linq к объектам? Или для связи?

Потому что ... выберите новый Mapper (c), требует, чтобы 'c' уже материализовался в объект, а затем был передан в Mapper () CTor. (поскольку «c» не известен на уровне БД, только на уровне .NET)

0
10.12.2008 18:23:01

Возможно, вам придется использовать цепочечные методы вместо синтаксиса LINQ, и тогда вы сможете передать любое из множества значений, которые вы укажете:Expression<Func<TSource, TResult>>

Expression<Func<CustomerTable, Customer>> someMappingExpression = c => new Customer { Name = c.Name };
return context.CustomerTable.Select(someMappingExpression);

UPDATE: Select берет Func, а не Expression
UPDATE: ВSelectфункциикоторая должна быть использована действительно приниматьExpression<Func>, а не простоFunc.

1
11.12.2008 15:44:31
Пример кода в этом примере является синтаксической ошибкой, не так ли? Также комментарий «Выбор принимает FUnc, а не выражение» некорректен для Linq to SQL.
Daniel Earwicker 10.12.2008 22:15:37

Кстати: решения, описанные здесь, будут работать, только если вы хотите использовать «факторизованную» часть кода в отдельном предложении запроса (например, Select). Если вы хотите использовать его как часть предложения, которое также выполняет некоторые другие функции (возможно, возвращает анонимный тип с некоторой другой информацией), вам необходимо динамически построить все дерево выражений, используя методы Expression.Xyz .

В качестве альтернативы вы можете использовать трюк для встраивания лямбда-выражений, которые я описал здесь:

0
17.02.2009 03:17:52