高效率 DataTable转实体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// dt:数据源 isconvert: false时需要确保datatable列类型与实体对应以免除类型转换,速度更快 true:会进行类型转换
        static List<T> ByExpTree<T>(DataTable dt, bool isconvert = false)
        {
            var props = typeof(T).GetProperties().Where(p => dt.Columns.Contains(p.Name)).Select(x => new { a = x });
            var param = Expression.Parameter(typeof(DataRow), "dr");
            List<Expression> exps = new List<Expression>();
            var cre = Expression.New(typeof(T));
            var newb = Expression.Variable(typeof(T));
            var assb = Expression.Assign(newb, cre);
            exps.Add(assb);
            MethodInfo field = typeof(DataRowExtensions).GetMethod("Field", new Type[] { typeof(DataRow), typeof(string) });<br><br>            // 使用时注意将Program改为 ChangeType所在类
            var mtd = isconvert ? typeof(Program).GetMethod("ChangeType", new Type[] { typeof(object) }) : null;
            foreach (var item in props)
            {
                var setexp = Expression.MakeMemberAccess(newb, item.a);
                BinaryExpression ass;
                if (isconvert)
                {
                    MethodInfo fieldext = field.MakeGenericMethod(typeof(object));
                    MethodCallExpression mceExpr = Expression.Call(fieldext, param, Expression.Constant(item.a.Name));
                    var mtdext = mtd.MakeGenericMethod(item.a.PropertyType);
                    var cvt = Expression.Call(mtdext, mceExpr);
                    ass = Expression.Assign(setexp, cvt);
                }
                else
                {
                    MethodInfo fieldext = field.MakeGenericMethod(item.a.PropertyType);
                    MethodCallExpression mceExpr = Expression.Call(fieldext, param, Expression.Constant(item.a.Name));
                    ass = Expression.Assign(setexp, mceExpr);
                }
                exps.Add(ass);
            }
            exps.Add(newb);
            var body = Expression.Block(new ParameterExpression[] { newb }, exps);
            var sel = Expression.Lambda<Func<DataRow, T>>(body, param);
            var dt2 = dt.AsEnumerable();
            return dt2.Select(sel.Compile()).ToList();
        }
         
        // 类型转换
        public static T ChangeType<T>(object value)
        {
            var t = typeof(T);
 
            if (t.IsGenericType && t.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
            {
                if (value == null)
                {
                    return default(T);
                }
 
                t = Nullable.GetUnderlyingType(t);
            }
 
            return (T)Convert.ChangeType(value, t);
        }

  PS: 部分代码来源于网络,调整改造成datatable转实体,此方式转换比反射速度快很,如果不作类型转换会更快, 仅作备忘记录;

posted @   Coder_小菜  阅读(447)  评论(0编辑  收藏  举报
编辑推荐:
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 对象命名为何需要避免'-er'和'-or'后缀
· SQL Server如何跟踪自动统计信息更新?
阅读排行:
· “你见过凌晨四点的洛杉矶吗?”--《我们为什么要睡觉》
· C# 从零开始使用Layui.Wpf库开发WPF客户端
· 编程神器Trae:当我用上后,才知道自己的创造力被低估了多少
· C#/.NET/.NET Core技术前沿周刊 | 第 31 期(2025年3.17-3.23)
· 接口重试的7种常用方案!
点击右上角即可分享
微信分享提示