2

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

这就是我卡住的地方。我可以创建一个使用表达式的方法,但是如何获取然后将这些字段映射到相应的 DAL 字段并获取尝试匹配的值。我不希望将 DAL 对象暴露给正在做表示层工作的最终开发人员。我对想法和建议持开放态度。

4

2 回答 2

0

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

需要考虑的另外两种方法:

  1. 使用存储库模式,调用者传入查询对象。DAL 将负责将该查询对象转换为表达式。我提出的一个问题中显示了存储库模式的一个示例。

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

    公共客户 GetCustomersById(int id) { ... }

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

于 2013-11-07T00:11:47.803 回答
0

So I think I have been able to find a solution to this. Using ExpressionVisitor and help from this post

I modified the VisitMember method:

    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);
    }

To pull the Attribute off of the Property of the Business Object.

To call everything I can do from the app:

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

Which calls a method in the business object

    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());
        }

Performance seems pretty good, I know there is going to be a hit with the mapping but it is something I can live with for now.

于 2013-11-12T19:57:55.993 回答