FastEntityCopy.cs 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Linq.Expressions;
  6. using System.Reflection;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. namespace NXWMS.Code.Entitys
  10. {
  11. /// <summary>
  12. /// 在两个不同的类型之间,快速的拷贝
  13. /// </summary>
  14. public static class FastEntityCopy
  15. {
  16. static ConcurrentDictionary<string, object> actions = new ConcurrentDictionary<string, object>();
  17. static Action<TSource, TTarget> CreateCopier<TSource, TTarget>()
  18. {
  19. var target = Expression.Parameter(typeof(TTarget));
  20. var source = Expression.Parameter(typeof(TSource));
  21. var props1 = typeof(TSource).GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p => p.CanRead).ToList();
  22. var props2 = typeof(TTarget).GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p => p.CanWrite).ToList();
  23. var props = props1.Where(x => props2.Where(y => y.Name == x.Name).Count() > 0);
  24. var block = Expression.Block(
  25. from p in props
  26. select Expression.Assign(Expression.Property(target, p.Name), Expression.Property(source, p.Name)));
  27. return Expression.Lambda<Action<TSource, TTarget>>(block, source, target).Compile();
  28. }
  29. /// <summary>
  30. /// 快速的拷贝同名公共属性。忽略差异的字段。
  31. /// </summary>
  32. /// <typeparam name="S"></typeparam>
  33. /// <typeparam name="T"></typeparam>
  34. /// <param name="from"></param>
  35. /// <param name="to"></param>
  36. public static void Copy<TSource, TTarget>(TSource from, TTarget to)
  37. {
  38. string name = string.Format("{0}_{1}", typeof(TSource), typeof(TTarget));
  39. object obj;
  40. if (!actions.TryGetValue(name, out obj))
  41. {
  42. var ff = CreateCopier<TSource, TTarget>();
  43. actions.TryAdd(name, ff);
  44. obj = ff;
  45. }
  46. Action<TSource, TTarget> act = (Action<TSource, TTarget>)obj;
  47. act(from, to);
  48. }
  49. }
  50. }