我有一个 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方法,但仅出于过滤目的提供了充分的灵活性。