Ef(EntityFramework) select 操作后Map到实体类型的方法

使用Ef 一直以来都有一个问题困扰着我,就是select 操作后在View页面 Render的时候非常麻烦,今日终于不胜其扰,下了一个方法,供大家参考。

controller :

1             var articleEntity = articleRepo.List().Where(x => x.AreaList.Select(s => s.Name).Contains("首页")).Select(x => new
2             {
3                 Title = x.Title,
4                 AreaList = x.AreaList,
5                 CoverPic = x.CoverPic
6             }).ToList().Map<List<Article>>();

Map方法:

 1  public static T Map<T>(this object obj)
 2             where T : class, new()
 3         {
 4             var objType = obj.GetType();
 5 
 6             if (objType.GetInterface("IList") == null)
 7             {
 8                 T t = new T();
 9 
10                 var srcType = t.GetType();
11 
12                 var srcTypeProps = srcType.GetProperties();
13 
14                 foreach (var property in objType.GetProperties())
15                 {
16                     var srcTypeProp = srcTypeProps.FirstOrDefault(x => x.Name == property.Name);
17 
18                     if (srcTypeProp != null)
19                     {
20                         srcTypeProp.SetValue(t, property.GetValue(obj));
21                     }
22                 }
23 
24                 return t;
25             }
26             else
27             {
28                 //obj 包含IList 接口则 T必须包含 
29                 try
30                 {
31                     var srcType = typeof(T);
32 
33                     if (srcType.GetInterface("IList") == null)
34                     {
35                         throw new Exception("数据值与目标值包含的结构不一致");
36                     }
37 
38                     var t = new T() as IList;
39 
40                     var objArgumentType = objType.GenericTypeArguments[0];
41 
42                     var objArgumentTypeProps = objArgumentType.GetProperties();
43 
44                     //获取泛型类型
45                     var srcTargetType = srcType.GenericTypeArguments[0];
46 
47                     var srcTargetTypeProps = srcTargetType.GetProperties();
48 
49                     foreach (var objItem in obj as IList)
50                     {
51                         var srcTargetTypeInstance = Activator.CreateInstance(srcTargetType);
52 
53                         foreach (var property in objArgumentTypeProps)
54                         {
55                             var srcProp = srcTargetTypeProps.FirstOrDefault(x => x.Name == property.Name);
56 
57                             if (srcProp != null)
58                             {
59                                 srcProp.SetValue(srcTargetTypeInstance, property.GetValue(objItem));
60                             }
61 
62                             //if (srcTargetTypeProps.Select(x => x.Name).Contains(property.Name))
63                             //{注意:这里因为用的objProp 给 srcTargetInstance 赋值,因为两者属于不同的类型,所以不可进行此操作.遂使用上方的方法,由srcProp给srcTargetInstance赋值
64                             //    property.SetValue(srcTargetTypeInstance, property.GetValue(objItem));
65                             //}
66                         }
67 
68                         //第二种方式
69                         //foreach (var property in srcTargetTypeProps)
70                         //{
71                         //    var objProperty = objArgumentTypeProps.FirstOrDefault(x => x.Name == property.Name);
72 
73                         //    if (objProperty != null)
74                         //    {
75                         //        property.SetValue(srcTargetTypeInstance, objProperty.GetValue(objItem));
76                         //    }
77                         //}
78 
79                         t.Add(srcTargetTypeInstance);
80                     }
81 
82                     return t as T;
83                 }
84                 catch (Exception exc)
85                 {
86                     throw;
87                 }
88             }
89         }

仅对IList接口做了处理,有需要的朋友可以继续扩展其他接口

原文地址:https://www.cnblogs.com/blackcatpolice/p/5546478.html