具有动态查询的DAL层

本文关键字:DAL 查询 动态 | 更新日期: 2024-09-23 22:23:37

我已经用ASP.NET MVC 5和实体框架开发了一个n层电子商务应用程序。我当然可以在未来更改我的DAL。但我可以弄清楚如何为动态查询嵌入我的DAL层。想象一下,用户在网站上列出产品,他们可以按产品类型或类别等进行筛选。也可以按价格或字母顺序等对产品进行排序。我的意思是,我需要完全动态的查询。在这一点上,我使用ef,如果我用ef创建动态查询,它不适合其他dal技术(nhibername、ado.net等)我该怎么办?

//in my controller
var db = ApplicationDbContext.Create();
IQueryable<Product> query = from q in db.Products
    where
        q.ProdType == ProdType.StorPerde && q.UserId == LoggedUserId &&
        !selectedStorPerdeId.Contains(q.ProdId)
    select q;
List<Product> prods = _productService.GetAll(query);
//service layer
public List<Product> GetAll(IQueryable<Product> query)
{
    return _productDal.GetAll(query);
}
//dal
public List<Product> GetAll(IQueryable<Product> query)
{
    return query.ToList();
}

具有动态查询的DAL层

首先,在当前的方法中,您甚至没有真正使用单独的数据访问层。您的控制器直接访问上下文,获得一个IQueryable,然后将其传递到服务层,只需在其上调用.ToList()。这违背了拥有单独层的全部意义。将您的逻辑完全移动到您的服务层中。

接下来,拥有服务层的目的是抽象数据源以及如何使用它。因此,应该围绕需要检索的特定信息创建服务层方法。例如,如果您需要获得特定用户的产品,那么您应该有一些方法,如GetProductsForUser(int userId)

最后,对于需要提交任意查询的更复杂的场景,可以允许服务层方法接受实际的过滤器:Get(Expression<Func<TEntity, bool>> filter)。该类型的参数将允许您传递标准的m => m.Foo == "Bar"样式where子句。然而,在这一点上,这是不太可移植的,因为过滤器更具体地实现。大多数ORM可能允许您从本质上使用这种类型的参数,但您可能需要跳过一些环节才能将其转换为对WebApi有用的参数。

您可能还想考虑将这样的任务卸载到像Elasticsearch这样的真正的搜索设备上。