標籤:style blog color 使用 strong 資料
項目背景, 採用貧血模式, 但希望在使用業務實體機商務規則上的資料屬性,使用同一規則。
比如:在頁面中, “RS_Department.Code" , "Department.Code"都可以正常訪問。
業務實體類
直接使用Linq to Sql 自動產生的程式碼,跟資料庫表一一對應。
如:RS_Requisition, RS_Department
商務規則類
實現資料庫增刪改查,擴充屬性,其他商務規則等。
public class Requisition : BLLTableCodeNameWraper<RS_Requisition> { public RS_Department Department(RS_Requisition data) { return data.RS_Department; } }
以上只是簡單樣本, 屬性可能需要訪問資料庫,可能需要快取資料結果。
如下是通過運算式樹狀架構實現的代碼:
public object GetBllValue(Base.IBLLQuery bll, object data, string path) { ParameterExpression bllExpr = Expression.Parameter(bll.GetType(), "bll"); ParameterExpression dataExpr = Expression.Parameter(data.GetType(), "data"); Expression b = bllExpr; Expression d = dataExpr; var properties = path.Split(‘.‘); foreach (var property in properties) { if (d.Type.GetProperties().Where(p => string.Compare(p.Name, property, true) == 0).Count() > 0) { d = MemberExpression.Property(d, property); } else if (bll.GetType().GetMethod(property) != null) { ///只能調用一次 d = Expression.Call(b, b.Type.GetMethod(property), d); } } ///效能考慮可以緩衝Func委託 var c = LambdaExpression.Lambda(d, bllExpr, dataExpr).Compile() ; return c.DynamicInvoke(bll, data)
測試代碼如下:
[TestMethod] public void TestBllEval() { var bll = new Requisition(); RS_Requisition data = new RS_Requisition(); data.RS_Department = new RS_Department() { DName = "a" }; string path = "Department.DName"; Expression<Func<Requisition, RS_Requisition, object>> e = (p, q) => p.Department(q).DName; var expect = e.Compile().Invoke(bll, data); var value = new EvalService().GetBllValue(bll, data, path); Assert.AreEqual(expect, value); }