Expression構建DataTable to Entity 映射委託

來源:互聯網
上載者:User

標籤:style   blog   color   使用   資料   io   for   cti   

 1 namespace Echofool.Utility.Common { 2     using System; 3     using System.Collections.Generic; 4     using System.Data; 5     using System.Linq.Expressions; 6     using System.Reflection; 7     using System.Reflection.Emit; 8  9     public class DataTableUtility {10 11         public static IEnumerable<T> Get<T>(DataTable table) where T : new() {12             if (table == null) {13                 yield break;14             }15             if (table.Rows.Count == 0) {16                 yield break;17             }18             foreach (DataRow row in table.Rows) {19                 yield return Get<T>(row);20             }21         }22 23         public static T Get<T>(DataRow row) where T : new() {24             return GenericCache<T>.Factory(row);25         }26 27         public class GenericCache<T> where T : new() {28             static GenericCache() {29                 //Factory = GetFactoryIL(); 這裡寫錯了
Factory = GetFactory();30 }31 public static readonly Func<DataRow, T> Factory;32 33 private static Func<DataRow, T> GetFactory() {34 var type = typeof(T);35 var rowType = typeof(DataRow);36 var rowDeclare = Expression.Parameter(rowType, "row");37 var instanceDeclare = Expression.Parameter(type, "instance");38 var newExpression = Expression.New(type);39 var instanceExpression = Expression.Assign(instanceDeclare, newExpression);40 var nullEqualExpression = Expression.Equal(rowDeclare, Expression.Constant(null));41 var containsMethod = typeof(DataColumnCollection).GetMethod("Contains");42 var indexerMethod = rowType.GetMethod("get_Item", BindingFlags.Instance | BindingFlags.Public, null,43 new[] { typeof(string) },44 new[] { new ParameterModifier(1) });45 var setExpressions = new List<Expression>();46 var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);47 var columns = Expression.Property(Expression.Property(rowDeclare, "Table"), "Columns");48 foreach (var propertyInfo in properties) {49 if (propertyInfo.CanWrite) {50 var propertyName = Expression.Constant(propertyInfo.Name, typeof(string));51 var checkIfContainsColumn =52 Expression.Call(columns, containsMethod, propertyName);53 var propertyExpression = Expression.Property(instanceDeclare, propertyInfo);54 var value = Expression.Call(rowDeclare, indexerMethod, propertyName);55 var proertyAssign = Expression.Assign(propertyExpression, Expression.Convert(value, propertyInfo.PropertyType));56 setExpressions.Add(Expression.IfThen(checkIfContainsColumn, proertyAssign));57 }58 }59 var checkIfRowIsNull = Expression.IfThenElse(nullEqualExpression, Expression.Empty(), Expression.Block(setExpressions));60 var body = Expression.Block(new[] { instanceDeclare }, newExpression, instanceExpression, checkIfRowIsNull, instanceDeclare);61 return Expression.Lambda<Func<DataRow, T>>(body, rowDeclare).Compile();62 } 63 }64 65 public static T GetByReflection<T>(DataRow dr) where T : new() {66 var t = new T();67 if (dr != null) {68 foreach (var p in typeof(T).GetProperties()) {69 if (!dr.Table.Columns.Contains(p.Name)) {70 continue;71 }72 var obj = dr[p.Name];73 var set = p.GetSetMethod();74 if (set == null) {75 continue;76 }77 p.SetValue(t, obj, null);78 }79 }80 return t;81 }82 }83 }


通過Expression動態構建DataTable映射到實體類,在三層架構中,如果使用的資料層是使用Ado.Net技術,那麼加上這個DataTable to Entity的工具類,將為你減少很多代碼量。

主要目的是解決DataTable到Entity的映射關係。   

 1         public class MyClass { 2             public MyClass() { } 3  4             public MyClass(DataRow row) { 5                 if (row != null) { 6                     if (row.Table.Columns.Contains("Name")) { 7                         this.Name = (string)row["Name"]; 8                     } 9                     if (row.Table.Columns.Contains("Age")) {10                         this.Age = (int)row["Age"];11                     }12                 }13             }14 15             public string Name { get; set; }16             public int Age { get; set; }17 18         }

如上定義的實體類MyClass,有一個string類型的Name屬性和一個int類型的Age屬性。

如果自訂建構函式是可以很方便的從DataRow對象中擷取資料填充實體類,但如果涉及的實體類太多,而且如果想通過定義特性標記 來實現一些欄位特殊處理,建構函式的方式,需要你寫太多的代碼,而且很多都是重複的邏輯。

現在使用DataTableUtility.Get<MyClass>.Get(row);就能很方便的擷取一個實體類。

現在使用DataTableUtility.Get<MyClass>.Get(table);就能很方便的擷取一個實體類集合。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.