字典缓存表达式树

作用

动态的将TIn对象赋值给TOut对象, 条件是TIn和TOut中的字段和属性相同

直接看代码

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;

namespace 字典缓存表达式树
{
    public class ExpressionMapper
    {
        //字典缓存
        private static Dictionary<string, object> _Dic = new Dictionary<string, object>();
        /// <summary>
        /// 字典缓存表达式树
        /// 作用:动态的将TIn对象赋值给TOut对象, 条件是TIn和TOut中的字段和属性相同
        /// </summary>
        /// <typeparam name="TIn"></typeparam>
        /// <typeparam name="TOut"></typeparam>
        /// <param name="tIn"></param>
        /// <returns></returns>
        public static TOut Trans<TIn, TOut>(TIn tIn)
        {
            string key = string.Format($"function_{0}_{1}", typeof(TIn).FullName, typeof(TOut).FullName);
            if(!_Dic.ContainsKey(key))
            {
                ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn), "p");
                List<MemberBinding> memberBindingList = new List<MemberBinding>();
                foreach(var item in typeof(TOut).GetProperties())
                {
                    MemberExpression property = Expression.Property(parameterExpression,typeof(TIn).GetProperty(item.Name));
                    MemberBinding memberBinding = Expression.Bind(item,property);//TOut.age = TIn.age赋值,   映射表达式
                    memberBindingList.Add(memberBinding);

                }
                foreach (var item in typeof(TOut).GetFields())
                {
                    MemberExpression property = Expression.Field(parameterExpression, typeof(TIn).GetField(item.Name));
                    MemberBinding memberBinding = Expression.Bind(item, property);//TOut.age = TIn.age赋值
                    memberBindingList.Add(memberBinding);
                }
                MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TOut)), memberBindingList.ToArray());//初始化表达式
                Expression<Func<TIn,TOut>> expression = Expression.Lambda<Func<TIn, TOut>>(memberInitExpression,new ParameterExpression[] { 
                    parameterExpression
                });
                Func<TIn, TOut> func = expression.Compile();
                _Dic[key] = func;
            }
            return ((Func<TIn, TOut>)_Dic[key]).Invoke(tIn);

        }
    }
}

其中_Dic(字典缓存字段)的作用

它是静态变量,存储的是两个对象转化的委托实现。

分析

第一次调用该方法时,需要拼装表达式树。但第二次在调用时,_Dic字段里已经缓存了该委托方法,直接到Invoke(),实现一定的性能提升,并且是泛型的。

应用场景

用EF创建的数据库实体类,在查询数据时我们一般不会直接返回EF映射的实体类,我们一般会在创建一个字段内容相同的数据返回类。此时就可以用上述方法了。

关于缓存的另一篇文章

泛型缓存

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菩提树下敲代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值