将业务层的通用查询转换为数据访问层

时间:2013-11-06 13:21:24

标签: c# architecture layer

我正在将遗留软件重写为.Net,并使用Linq 2 SQL创建了一个数据访问层,它运行良好。我正在使用的数据库有超过230个表,而不是我真正能改变的。我遇到的问题是业务层。我希望开发人员能够查询业务对象并将这些查询映射到数据层。像Customers.Query(c=>c.ID=="MyID")之类的东西 并且能够将其传递给我的DAL,context.CUSTOMERS.Query(c=>c.UID == "MyID") 我的DAL中有通用的Query方法,允许我传入DAL查询。

这是我被困的地方。我可以创建一个使用Expression的方法,但是如何获取然后将这些字段映射到相应的DAL字段并获取试图匹配的值。我不想要的是必须将DAL对象暴露给正在进行表示层事务的最终开发人员。我对这些想法和建议持开放态度。

2 个答案:

答案 0 :(得分:0)

开发人员是否需要使用表达式查询业务对象?我问的原因是因为映射表达式可能很复杂。在某些时候,必须进行一些映射。 DAL通常是将DB对象转换为域对象的映射层,反之亦然。

另外两种方法:

  1. 使用存储库模式,调用者传入查询对象。 DAL负责将该查询对象转换为表达式。存储库模式的示例显示在question that I asked

  2. 公开更具体的方法,例如:

    public Customer GetCustomersById(int id){...}

  3. 我相信这两种方法中的任何一种都会使查询变得更容易。

答案 1 :(得分:0)

所以我认为我已经找到了解决方案。使用ExpressionVisitorthis post

的帮助

我修改了VisitMember方法:

    protected override Expression VisitMember(MemberExpression node)
    {
        string sDbField = ((SFWBusinessAttributes)node.Expression.Type.GetProperty(node.Member.Name).GetCustomAttribu`tes(typeof(SFWBusinessAttributes), true)[0]).DBColumn;
        var expr = Visit(node.Expression);
        if (expr.Type != node.Type)
        {
            MemberInfo newMember = expr.Type.GetMember(sDbField).Single();
            return Expression.MakeMemberAccess(expr, newMember);
        }
        return base.VisitMember(node);
    }

从属性中拉出属性。

通过应用程序调用我能做的所有事情:

    BusObj.Query(a => a.IsDeleted != true && a.Company.Contains("Demo"))

调用业务对象中的方法

    public List<Account> Query(Expression<Func<Account, bool>> expression)
    {
        using (Data.CustomerData data = new Data.CustomerData(_connstring))
        {
             return MapList(data.Query<Data.Database.ACCOUNT>(expression.Convert<Account, Data.Database.ACCOUNT>()).ToList());
        }

性能似乎相当不错,我知道地图会受到影响但是我现在可以忍受这种情况。