C# 使用嵌套集合属性动态生成LINQ select
这个问题非常类似于C# 使用嵌套集合属性动态生成LINQ select,c#,linq,select,expression,linq-expressions,C#,Linq,Select,Expression,Linq Expressions,这个问题非常类似于 publicstaticexpressionbuildselector(字符串成员)=> BuildSelector(members.Split(',).Select(m=>m.Trim()); 公共静态表达式构建选择器(IEnumerable成员) { var参数=表达式参数(typeof(TSource),“e”); var body=NewObject(typeof(TTarget),参数,members.Select(m=>m.Split('.')); 返回表达式.L
publicstaticexpressionbuildselector(字符串成员)=>
BuildSelector(members.Split(',).Select(m=>m.Trim());
公共静态表达式构建选择器(IEnumerable成员)
{
var参数=表达式参数(typeof(TSource),“e”);
var body=NewObject(typeof(TTarget),参数,members.Select(m=>m.Split('.'));
返回表达式.Lambda(主体,参数);
}
静态表达式NewObject(类型targetType,表达式源,IEnumerable MemberPath,int-depth=0)
{
var bindings=newlist();
var target=Expression.Constant(null,targetType);
foreach(memberpath.GroupBy(path=>path[depth])中的var memberGroup)
{
var memberName=memberGroup.Key;
var targetMember=Expression.PropertyOrField(target,memberName);
var sourceMember=Expression.PropertyOrField(source,memberName);
var childMembers=memberGroup.Where(路径=>depth+1
Ivan Stoev提供的尼斯通用解决方案运行良好,但问题是它不支持集合属性
例如,source.Property1.Property2-如果Property1是用户的集合,则代码不起作用,因为Property2不是集合的属性,而是Property1类型的属性
class Shipment {
// other fields...
public int Id;
public Address Sender;
public List<Address> Recipients;
}
class Address {
public string AddressText;
public string CityName;
public string CityId;
}
类装运{
//其他领域。。。
公共int Id;
公共广播发送者;
公开名单收件人;
}
班级地址{
公共字符串地址文本;
公共字符串CityName;
公共字符串CityId;
}
通过上面的类和代码,我可以查询
var test = BuildSelector<Shipment, Shipment>(
"Id, Sender.CityId, Sender.CityName");
var测试=构建选择器(
“Id,Sender.CityId,Sender.CityName”);
但是,如果我只想获取收件人的城市名称,我无法执行以下操作(因为收件人是集合):
var测试=构建选择器(
“收件人。城市名称”);
我对C#表达式不熟悉,不知道如何改进上述解决方案,使其与集合属性一起工作。这是一个解决方案。目前,它处理集合
公共静态类ExpressionHelpers
{
公共静态表达式构建选择器(字符串成员)=>
BuildSelector(members.Split(',).Select(m=>m.Trim());
公共静态表达式构建选择器(IEnumerable成员)
{
var参数=表达式参数(typeof(TSource),“e”);
var body=NewObject(typeof(TTarget),参数,members.Select(m=>m.Split('.'));
返回表达式.Lambda(主体,参数);
}
静态表达式NewObject(类型targetType,表达式源,IEnumerable MemberPath,int-depth=0)
{
var bindings=newlist();
var target=Expression.Constant(null,targetType);
foreach(memberpath.GroupBy(path=>path[depth])中的var memberGroup)
{
var memberName=memberGroup.Key;
var targetMember=Expression.PropertyOrField(target,memberName);
var sourceMember=Expression.PropertyOrField(source,memberName);
var childMembers=memberGroup.Where(path=>depth+1var test = BuildSelector<Shipment, Shipment>(
"Id, Sender.CityId, Sender.CityName");
var test = BuildSelector<Shipment, Shipment>(
"Recipients.CityName");