LINQ - 将 MemberBinding 表达式追加到现有的 MemberInit 表达式中
LINQ - append MemberBinding expression into exist MemberInit expression
基本思路类似于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
};
现在,我想'append'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
,但没有成功。
除了两个选择器的"merge"外,你还必须将"path"o => o.Extra
插入extraSelector
并为"bind expression"创建一个新的"bind expression" UserDto
的 属性 Extra
。
事实上,我在 this project 中尝试过这样的场景,我试图在其中抽象出这种表达式管道。你的 "merge" 看起来像这样:
userSelector = extraSelector.Translate()
.Cross<User>(o => o.Extra)
.Apply(o => o.Extra, userSelector);
Translate
扩展方法只是利用类型推断的一个小帮手,Cross
将o => o.Extra
插入extraSelector
,Apply
创建"bind expression" 用于 UserDto
的 属性 Extra
最后将结果与 userSelector
.
合并
基本思路类似于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
};
现在,我想'append'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
,但没有成功。
除了两个选择器的"merge"外,你还必须将"path"o => o.Extra
插入extraSelector
并为"bind expression"创建一个新的"bind expression" UserDto
的 属性 Extra
。
事实上,我在 this project 中尝试过这样的场景,我试图在其中抽象出这种表达式管道。你的 "merge" 看起来像这样:
userSelector = extraSelector.Translate()
.Cross<User>(o => o.Extra)
.Apply(o => o.Extra, userSelector);
Translate
扩展方法只是利用类型推断的一个小帮手,Cross
将o => o.Extra
插入extraSelector
,Apply
创建"bind expression" 用于 UserDto
的 属性 Extra
最后将结果与 userSelector
.