在服务层方法中将 IQueryable 作为参数传递是否是一种好的做法



我有一个 ASP.NET 应用程序,其中包含 3 层 UI服务层存储库

我必须在数据库中的产品上实现搜索功能ProductRepository是我的存储库类,从数据库中获取所有产品的方法的签名为:

IQueryable<Product> GetAllProducts();

因此,从我的服务层,我使用:

IProductRepository _ProductRepository = new ProductRepository(); 
IQueryable<Product> products = _ProductRepository.GetAllProducts();

如果我想过滤IQueryable<Product> products,例如,通过价格> 100 或仅采用颜色 = "黄色">的产品。

所以我想知道,而不是在ProductRepository中创建方法,例如:

IQueryable<Product> GetAllProductsByColor(int colorId)

我想知道在我的服务层中创建一组接受IQueryable<Product>作为参数并直接在那里执行过滤的方法是否是一种好的做法:

IQueryable<Product> FilterProducts(IQueryable<Product> products, Dictionary<string, object> filters)

其中Dictionary<string, string>表示具有(属性名称,值(的集合。

此解决方案的优点是,如果我必须应用多个过滤器,我只需传递已过滤IQueryable<Product>,而不是每次都获取过滤后产品集之间的交集。

这是一种好的做法(只要我保持上下文开放(还是多层架构模式不允许"这样做?

我想

说这取决于是什么提供了你的IQueryable的实现。在大多数情况下,您冒着允许 IQueryable 用户 1( 过滤未索引的字段的风险(因此,当您有大型表时,如果有的话,则会占用数据库层(,或者 2( 执行任意 IQueryable 操作,这些操作会给数据库带来巨大的负载(例如 GroupBy、Join 等(。

假设你对 1 没问题,以防止 2(我通常允许用户通过IEnumerable<Product> LoadProducts(Predicate<Product> filter)方法加载对象,然后将其转换为IQueryable上的Where;这隐藏了其他IQueryable方法,但仅出于过滤目的提供了充分的灵活性。

最新更新