利用表达式树合并对象

js我们常用这种写法

{...a,...b}

C#中有时候也需要这样写,比如使用EFCore查询单表,又需要从另一张表取两个字段,两张表的字段合并到一个对象里面,最后返回一个集合

典型的就是b表只存了外键人员id,需要查询a表和a表中外键对应的姓名

比如

student { studentName, sid },学生表

course { courseName, cid },课程表

score { sid , courseName,cid, score }得分表

最后要从得分表取字段返回学生每课分数

course { sid courseName,cid, scorestudentName}

为了显示,这就需要再加上一个课程名

我们首先构造一个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 }));
            }

最终就能得到想要的集合

 

posted @ 2024-03-01 14:44  ggtc  阅读(16)  评论(0编辑  收藏  举报
//右下角目录