我使用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();
}
答案 0 :(得分:1)
嗯,首先,你现在甚至没有使用这种当前方法的单独数据访问层。您的控制器直接访问上下文获取IQueryable
,然后您将其传递到服务层,只需在其上调用.ToList()
即可。这打破了拥有单独一层的全部意义。完全将您的逻辑移到服务层。
接下来,拥有服务层的目的是抽象数据源以及如何使用它。因此,应围绕需要检索的特定信息创建服务层方法。例如,如果您需要获取特定用户的产品,则应该使用GetProductsForUser(int userId)
等方法。
最后,对于需要能够提交任意查询的更复杂方案,您可以允许服务层方法接受实际过滤器:Get(Expression<Func<TEntity, bool>> filter)
。该类型的参数将允许您传递标准m => m.Foo == "Bar"
样式where子句。但是,此时此功能不太便携,因为过滤器更具实现性。大多数ORM可能允许你本质地使用这种类型的参数,但是你可能需要跳过几个环来将它转换为对Web Api这样的东西有用的东西。
您可能还想考虑将此类任务卸载到像Elasticsearch这样的真实搜索设备。