具有动态查询的 DAL 层
DAL Layer With Dynamic Query
我使用 ASP.NET MVC 5 和 entity framework 开发了一个 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();
}
嗯,首先,您实际上并没有使用当前的这种方法使用单独的数据访问层。您的控制器直接访问上下文获取 IQueryable
,然后将其传递到您的服务层,只需调用 .ToList()
即可。这破坏了拥有单独层的全部意义。将您的逻辑完全移至您的服务层。
接下来,拥有服务层的要点是抽象数据源以及您如何使用它。因此,您的服务层方法应该围绕您需要检索的特定信息创建。例如,如果你需要获取特定用户的产品,你应该有一些像 GetProductsForUser(int userId)
.
这样的方法
最后,对于需要能够提交任意查询的更复杂的场景,您可以允许您的服务层方法接受实际过滤器:Get(Expression<Func<TEntity, bool>> filter)
。该类型的参数将允许您传递标准 m => m.Foo == "Bar"
样式的 where 子句。然而,这在这一点上可移植性较差,因为过滤器更特定于实现。大多数 ORM 可能允许您本质上使用这种类型的参数,但您可能必须跳过几个步骤才能将其转换为对 Web 等有用的东西 Api.
您可能还想考虑将此类任务卸载到 Elasticsearch 等真正的搜索设备。
我使用 ASP.NET MVC 5 和 entity framework 开发了一个 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();
}
嗯,首先,您实际上并没有使用当前的这种方法使用单独的数据访问层。您的控制器直接访问上下文获取 IQueryable
,然后将其传递到您的服务层,只需调用 .ToList()
即可。这破坏了拥有单独层的全部意义。将您的逻辑完全移至您的服务层。
接下来,拥有服务层的要点是抽象数据源以及您如何使用它。因此,您的服务层方法应该围绕您需要检索的特定信息创建。例如,如果你需要获取特定用户的产品,你应该有一些像 GetProductsForUser(int userId)
.
最后,对于需要能够提交任意查询的更复杂的场景,您可以允许您的服务层方法接受实际过滤器:Get(Expression<Func<TEntity, bool>> filter)
。该类型的参数将允许您传递标准 m => m.Foo == "Bar"
样式的 where 子句。然而,这在这一点上可移植性较差,因为过滤器更特定于实现。大多数 ORM 可能允许您本质上使用这种类型的参数,但您可能必须跳过几个步骤才能将其转换为对 Web 等有用的东西 Api.
您可能还想考虑将此类任务卸载到 Elasticsearch 等真正的搜索设备。