LINQ - добавить выражение MemberBinding в существующее выражение MemberInit

1

Основная идея аналогична объединению деревьев выражений для повторного использования в запросах Linq.

В моей ситуации у меня две модели и DTO:

public class User
{
  public int Id { get; set; }
  public string Name { get; set; }
  public Extra Extra { get; set; }
}
public class Extra
{
  public int Id { get; set; }
  public string Text { get; set; }
}
public class UserDto
{
  public int Id { get; set; }
  public string Name { get; set; }
  public ExtraDto Extra { get; set; }
}
public class ExtraDto
{
  public int Id { get; set; }
  public string Text { get; set; }
}

и выражения:

Expression<Func<Extra, ExtraDto>> extraSelector = o => new ExtraDto
{
  Id = o.Id,
  Text = o.Text
};
Expression<Func<User, UserDto>> userSelector = o => new UserDto
{
  Id = o.Id,
  Name = o.Name
};

Теперь я хотел бы добавить " extraSelector в userSelector. Псевдокод выглядит так:

var selectorExpression = userSelector.Append(user => user.Extra, extraSelector);
Context.Users.Select(selectorExpression).ToList();

Окончательное выражение будет следующим:

Expression<Func<User, UserDto>> userSelector = o => new UserDto
{
  Id = o.Id,
  Name = o.Name,
  Extra = new ExtraDto
  {
    Id = o.Extra.Id,
    Text = o.Extra.Text
  }
};

Я попытался использовать ExpressionVisitor, но не повезло.

Теги:
linq

1 ответ

1
Лучший ответ

Помимо "слияния" двух селекторов, вы должны вставить "путь" o => o.Extra в extraSelector и создать новое "выражение привязки" для свойства Extra of UserDto.

На самом деле, я играю с такими сценариями в рамках этого проекта, где я пытался абстрагироваться от такого типа выражения. Тогда ваше "слияние" будет выглядеть так:

userSelector = extraSelector.Translate()
                            .Cross<User>(o => o.Extra)
                            .Apply(o => o.Extra, userSelector);

Метод расширения Translate - это всего лишь небольшой помощник, чтобы использовать вывод типа, Cross inserts o => o.Extra в extraSelector, Apply создает "выражение привязки" для свойства Extra of UserDto и, наконец, объединяет результат с userSelector.

  • 0
    Отличный проект! Я реализовал что-то вроде «повторного использования селектора», но этот проект намного лучше моего. Благодарю.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню