具有动态查询的DAL层

时间:2015-03-02 16:51:56

标签: c# asp.net-mvc entity-framework n-tier-architecture

我使用ASP.NET MVC 5和实体框架开发了一个n层电子商务应用程序。 Mybe当然我可以在将来改变我的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();
}

1 个答案:

答案 0 :(得分:1)

嗯,首先,你现在甚至没有使用这种当前方法的单独数据访问层。您的控制器直接访问上下文获取IQueryable,然后您将其传递到服务层,只需在其上调用.ToList()即可。这打破了拥有单独一层的全部意义。完全将您的逻辑移到服务层。

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

最后,对于需要能够提交任意查询的更复杂方案,您可以允许服务层方法接受实际过滤器:Get(Expression<Func<TEntity, bool>> filter)。该类型的参数将允许您传递标准m => m.Foo == "Bar"样式where子句。但是,此时此功能不太便携,因为过滤器更具实现性。大多数ORM可能允许你本质地使用这种类型的参数,但是你可能需要跳过几个环来将它转换为对Web Api这样的东西有用的东西。

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