LINQ - 将MemberBinding表达式追加到现有的MemberInit表达式中

时间:2015-01-19 13:06:08

标签: c# linq

基本理念与Merging Expression Trees to Reuse in Linq Queries类似。

在我的情况下,我有两个模型和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

我尝试使用{{1}},但没有运气。

1 个答案:

答案 0 :(得分:1)

除了两个选择器的“合并”之外,您必须将“路径”o => o.Extra插入extraSelector并为属性Extra创建一个新的“绑定表达式” UserDto

事实上,我在this project内玩这种场景,我试图抽象这种表达方式。你的“合并”看起来就是这样:

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

Translate扩展方法只是帮助使用类型推断,Crosso => o.Extra插入extraSelectorApply创建“绑定表达式“为Extra的属性UserDto,最后将结果与userSelector合并。