• C#ORM中的对象映射


    使用Linq.Expressions来动态生成映射方法

      1.我们先写个简单的类Test,包含一个ID和Name。

    public class Test
    {
       public int? ID { get; set; }
       public string Name { get; set; }
     }

      2.需要手工写简单映射代码,暂时不考虑大小写等问题,代码如下。

            /// <summary>
            /// 设置属性
            /// </summary>
            static void Set(Test t,string name,object value)
            {
                switch (name)
                {
                    case "ID":t.ID = Convert.ToInt32(value);break;
                    case "Name": t.Name = Convert.ToString(value); break;
                }
            }
            /// <summary>
            /// 获取属性
            /// </summary>
            static Object Get(Test t, string name)
            {
                switch (name)
                {
                    case "ID": return t.ID;
                    case "Name": return t.Name;
                }
                return null;
            }

      3.目标就是通过Expressions来自动产生上面2个方法,先定义Set方法的3个参数Test ,name,value(不了解Expressions点击

    ParameterExpression val = Expression.Parameter(typeof(object));//value
    ParameterExpression instance = Expression.Parameter(typeof(object));//Test 
    ParameterExpression nameexp = Expression.Parameter(typeof(string));//name

       4.通过反射得到所有的属性集合,再根据属性集合产生case 语句,以下为Set方法的表达式

    var ps = t.GetProperties();//t为typeof(Test)
    List<SwitchCase> lt = new List<SwitchCase>();
    foreach (var n in ps)
      {
         if (!n.CanWrite) { continue; }
         Expression tp = Expression.Convert(val, n.PropertyType); //类型转换,此为隐式转换。目前不考虑强行转换类型
         lt.Add(Expression.SwitchCase(Expression.Call(Expression.Convert(instance, t), n.GetSetMethod(), tp), Expression.Constant(n.Name)));
     }
     Expression p1 = Expression.Switch(nameexp, lt.ToArray());
    LambdaExpression exp = Expression.Lambda(p1, instance, nameexp, val);//转换为LambdaExpression 后就可以编译了
    Action<object, string, object> act = exp.Compile() as Action<object, string, object>;

      5.Get方法的表达式

    var ps = t.GetProperties();
    List<SwitchCase> lt = new List<SwitchCase>();
    ParameterExpression instance = Expression.Parameter(typeof(object));
    ParameterExpression nameexp = Expression.Parameter(typeof(string));
    foreach (var n in ps)
      {
         if (!n.CanRead) { continue; }
         lt.Add(Expression.SwitchCase(Expression.Convert(Expression.Call(Expression.Convert(instance, t), n.GetGetMethod(), null), typeof(object)), Expression.Constant(n.Name)));
      }
    Expression p1 = Expression.Switch(nameexp, Expression.Constant(null), lt.ToArray());
    LambdaExpression exp = Expression.Lambda(p1, instance, nameexp);
    Func<object, string, object> func = exp.Compile() as Func<object, string, object>;

      以上只是简单的案例代码,用于说明Expression来产生映射代码,查看完整代码,虽然更多人用Emit,但本质是一样。

  • 相关阅读:
    xcode构建webdriverAgent时报错Messaging unqualified id的解决办法
    ubuntu18.0安装RabbitMQ
    python中*的用法
    Jenkins构建项目
    Jenkins安装与配置
    git_仓库
    六、 Shell数组应用
    五、 Shell函数应用
    三、 Shell流程控制
    二、 Shell变量定义
  • 原文地址:https://www.cnblogs.com/xuzhiqiang/p/9495213.html
Copyright © 2020-2023  润新知