標籤:lin code set null rop soft class 說明 stat
使用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));//valueParameterExpression 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,但本質是一樣。
C#ORM中的對象映射