Используйте делегата к Проекции в Linq к SQL

Я имею, кодируют что-то вроде этого в реализации IRepository в Linq к Sql:

var newlist = from h in list where h.StringProp1 == "1"
                      select new MyBusinessBO{
                          firstProp = h.StringProp1,
                          secondProp = h.StringProp2
                      };

Проекция в MyBusinessBO не является difificult, но когда Бизнес-объект имеет много свойств, код проекции становится очень длинным. Кроме того, поскольку проекция может произойти в нескольких местах в Репозитории, мы повреждаем принцип DRY.

Там какой-либо путь состоит в том, чтобы абстрагировать проекцию или заменить ее делегатом?

Т.е. замените код

                          firstProp = h.StringProp1,
                          secondProp = h.StringProp2

с чем-то допускающим повторное использование?

9
задан Redeemed1 25 May 2010 в 05:36
поделиться

4 ответа

Queryable.Select требует Expression > . Вы можете написать метод, который возвращает это значение, и использовать этот метод везде, где вы выполняете преобразование.

public Expression<Func<DataObj, BusiObj>> GetExpr()
{
  return h => new BusiObj()
  {
    firstProp = h.StringProp1,
    secondProp = h.StringProp2
  };
}


 //get a local variable holding the expression.
Expression<Func<DataObj, BusiObj>> toBusiObj = GetExpr();

//use it thusly
var newList = (from h in list where h.StringProp1 == "1" select h)
  .Select(toBusiObj)
  .ToList();

//or
List<BusiObj> newList = list
  .Where(h => h.StringProp1 == "1")
  .Select(toBusiObj)
  .ToList();
5
ответ дан 2 November 2019 в 23:59
поделиться

Возможно, используйте обычные недефолтные конструкторы, а не инициализаторы объектов. Или, если вы можете начать использовать C# 4.0, попробуйте добавить опциональные/дефолтные параметры.

0
ответ дан 2 November 2019 в 23:59
поделиться

Эту проблему можно решить, используя синтаксис с точкой, а не синтаксис в стиле LINQ.

Ваш текущий:

list
    .Where(h => h.StringProp1 == "1")
    .Select(h => new MyBusinessBO
    {
        firstProp = h.StringProp1,
        secondProp = h.StringProp2
    });

Возможное решение:

Func<MyType, MyBusinessBO> selector = h => new MyBusinessBO
{
    firstProp = h.StringProp1,
    secondProp = h.StringProp2
};
list
    .Where(h => h.StringProp1 == "1")
    .Select(selector);

И вы можете передать селектор где-нибудь или сгенерировать его на лету или что-то в этом роде.

7
ответ дан 2 November 2019 в 23:59
поделиться

Взгляните на AutoMapper и аналогичные инструменты

0
ответ дан 2 November 2019 в 23:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: