利用表达式树合并对象
js我们常用这种写法
{...a,...b}
C#中有时候也需要这样写,比如使用EFCore查询单表,又需要从另一张表取两个字段,两张表的字段合并到一个对象里面,最后返回一个集合
典型的就是b表只存了外键人员id,需要查询a表和a表中外键对应的姓名
比如
student { studentName, sid },学生表
course { courseName, cid },课程表
score { sid , courseName,cid, score }得分表
最后要从得分表取字段返回学生每课分数
course { sid , courseName,cid, score,studentName}
为了显示,这就需要再加上一个课程名
我们首先构造一个DTO继承于score,在自定义一个studentName字段
class course:score{ public string studentName{get;set; } }
然后用表达式树来实现{...a,...b}这个功能
var para = Expression.Parameter(typeof(student), "input1"); var para2 = Expression.Parameter(typeof(course), "input2"); var properties1 = typeof(student).GetProperties(); var properties2 = typeof(course).GetProperties().Where(r => properties1.Count(x => x.Name == r.Name) == 0); var bindings = properties1.Select(r => Expression.Bind(typeof(course).GetProperty(r.Name), Expression.Property(para, r))); var bindings2 = properties2.Select(r => Expression.Bind(typeof(course).GetProperty(r.Name), Expression.Property(para2, r))); //新建对象 var newExpression = Expression.New(typeof(course)); //初始化对象 var memberInitExpression = Expression.MemberInit(newExpression, bindings.Union(bindings2)); // var lambda = Expression.Lambda<Func<student, course, course>>(memberInitExpression, para, para2); var combinefunc = lambda.Compile();
我们利用linq获取的集合可能是这样的结构
rows: { scores:socre类型, studentName:string类型 }
我们在foreach中构建要返回的集合
List<course> lst = new List<course>(); foreach (var item in rows) { lst.Add(combinefunc(item.a, new course { item.studengName })); }
最终就能得到想要的集合