在服务层方法中将IQueryable作为参数传递是一种好习惯吗?

时间:2012-05-04 14:53:50

标签: asp.net parameters filter iqueryable service-layer

我有一个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>,而不是每次都过滤过滤产品集之间的交集。

这是一个好习惯(只要我保持上下文打开),或者多层架构模式不允许“允许”这样做吗?

1 个答案:

答案 0 :(得分:2)

我会说这取决于提供IQueryable实现的内容。在大多数情况下,您可能会允许IQueryable的用户1)过滤未编制索引的字段(因此,如果您有任何大型表,则使用数据库层,或者2)执行任意IQueryable对数据库施加巨大负担的操作(例如GroupBy,Join等)。

假设您对1没问题,为了防止2)我通常允许用户通过IEnumerable<Product> LoadProducts(Predicate<Product> filter)方法加载对象,然后我将其转换为IQueryable上的Where;这隐藏了其他IQueryable方法,但仍允许完全灵活地进行过滤。

相关问题