采用表达式树提升属性访问性能

 

项目背景, 采用贫血模式, 但希望在使用业务实体机业务规则上的数据属性,使用同一规则。

比如:在页面中, “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);
    }

 

 

 

posted @ 2014-07-12 17:11  iyxqj  阅读(221)  评论(0编辑  收藏  举报