我有一个ASP.NET应用程序,包含3层 UI ,服务层和存储库。
我必须在数据库中的产品上实施搜索功能。
ProductRepository
是我的存储库类,并且从数据库中获取所有产品的方法的签名是:
IQueryable<Product> GetAllProducts();
因此,从我的服务层,我使用:
IProductRepository _ProductRepository = new ProductRepository();
IQueryable<Product> products = _ProductRepository.GetAllProducts();
如果我想过滤IQueryable<Product> products
,例如将这些产品用价格&gt; 100 或只是那些 color =“yellow”的人。
所以我想知道,而不是在ProductRepository
中创建方法,例如:
IQueryable<Product> GetAllProductsByColor(int colorId)
我想知道在我的服务层中创建一组接受IQueryable<Product>
作为参数并直接在那里执行过滤的方法是不错的做法:
IQueryable<Product> FilterProducts(IQueryable<Product> products, Dictionary<string, object> filters)
Dictionary<string, string>
代表(propertyName,value)的集合。
此解决方案的优点是,如果我必须应用多个过滤器,我只需传递已过滤的IQueryable<Product>
,而不是每次都过滤过滤产品集之间的交集。
这是一个好习惯(只要我保持上下文打开),或者多层架构模式不允许“允许”这样做吗?
答案 0 :(得分:2)
我会说这取决于提供IQueryable实现的内容。在大多数情况下,您可能会允许IQueryable的用户1)过滤未编制索引的字段(因此,如果您有任何大型表,则使用数据库层,或者2)执行任意IQueryable对数据库施加巨大负担的操作(例如GroupBy,Join等)。
假设您对1没问题,为了防止2)我通常允许用户通过IEnumerable<Product> LoadProducts(Predicate<Product> filter)
方法加载对象,然后我将其转换为IQueryable上的Where
;这隐藏了其他IQueryable方法,但仍允许完全灵活地进行过滤。