Инкапсуляция оператора выбора LINQ - PullRequest
2 голосов
/ 10 декабря 2008

У меня есть оператор LINQ, который выглядит следующим образом:

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

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

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

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

Edit:

Это для LINQ to SQL.

Ответы [ 4 ]

4 голосов
/ 10 декабря 2008

Новый ответ теперь я заметил, что это 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);
1 голос
/ 10 декабря 2008

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

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

ОБНОВЛЕНИЕ: Select занимает Func, а не Expression
ОБНОВЛЕНИЕ: Функция Select, которую следует использовать принимает вместо Func.

Expression<Func>.
0 голосов
/ 17 февраля 2009

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

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

0 голосов
/ 10 декабря 2008

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...