我正在将遗留软件重写为.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对象暴露给正在进行表示层事务的最终开发人员。我对这些想法和建议持开放态度。
答案 0 :(得分:0)
开发人员是否需要使用表达式查询业务对象?我问的原因是因为映射表达式可能很复杂。在某些时候,必须进行一些映射。 DAL通常是将DB对象转换为域对象的映射层,反之亦然。
另外两种方法:
使用存储库模式,调用者传入查询对象。 DAL负责将该查询对象转换为表达式。存储库模式的示例显示在question that I asked。
公开更具体的方法,例如:
public Customer GetCustomersById(int id){...}
我相信这两种方法中的任何一种都会使查询变得更容易。
答案 1 :(得分:0)
所以我认为我已经找到了解决方案。使用ExpressionVisitor和this 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());
}
性能似乎相当不错,我知道地图会受到影响但是我现在可以忍受这种情况。