MVC - 领域服务负责过滤还是仓储层?

6

我需要过滤来自域服务的IQueryable结果吗?

例如...我的三个门户网站都访问同一个域服务层,根据用户类型调用特定的存储库方法并返回结果。

当前的存储库层:

    IQueryable<Products> GetAllProductsForCrazyUserNow(CrazyUser id);
    Products GetAProductForCrazyUserNow(CrazyUser id,product id);

    IQueryable<Products> GetProductsForNiceUserNow(NiceUser id);
    Products GetProductsForNiceUserNow(NiceUser id,product id);

最好是在存储库层面完成这个操作:

    IQueryable<Products> GetAllProducts();
    Products GetAProduct(product id);

然后在域服务中,我只需进行过滤,即:

var Niceman = IQueryable<Products> GetAllProducts().Where(u=> u.Name == "Nice");

注意:我有一个只读会话和一个包含仓库层CRUD操作的会话,请在回答时牢记这一点。

第二个问题:我是否应该在领域服务层进行任何过滤?这个层级是唯一可以修改实体的层级,比如 Product.Price == 25.00;这不会被委托给仓库层。

3个回答

3

我通常使用代码仓库层来执行简单的CRUD操作,将业务逻辑或筛选需要在传回UI层之前在领域层中执行。

将业务/筛选逻辑与仓库层分离将有助于保持代码整洁。此外,如果将来要更改数据访问模式,则无需更改代码工作方式,因为它将在您的领域层中分离。


我们可以认为仓储层是用于持久化和检索基本数据集的,然后它们应该在域服务中进行细化。也就是说,如果我们不考虑存储过程...我很高兴我不需要处理这个问题,因为我正在使用LinqToSql。 - Haroon

2

哈鲁,

我在仓储之外使用 IQueryable<Classes> 上的扩展方法。 实际上,我有一组称为“过滤器”的类,它们通常是以下内容:

public static class ProductFilters
{
    public static IQueryable<Products> NiceMan(
        this IQueryable<Products> customQuery, string filterName)
    {
        if (!string.IsNullOrEmpty(filterName))
           customQuery = customQuery.Where(u => u.Name == filterName);
        return customQuery;
    }
   // create lots of other Products based filters here
   // and repeat with seperate IQueryable<Classes> per type
}

用法:

var Niceman = IQueryable<Products> GetAllProducts().NiceMan("Nice");

我认为这是一种很好的逻辑分离,可以保持代码库的整洁。对于第二个问题的回答是,是的,将此过滤器/扩展逻辑用于服务层,而不是仅用于代码库。


感谢您的答案,我已经点赞了您,因为您的描述更加清晰明了! - Haroon

0

我自己也曾经有过同样的问题。我不愿意将其放在服务层中的原因是,在某些情况下,过滤过程可能会从存储库中删除大部分记录,我不想从数据库中拉取比必要更多的数据。

最终,我转向了NHibernate,并使我的存储库方法接受DetachedCriteria参数。然后,我将用户信息传递到服务层,并让它通过构造一个DetachedCriteria对象并将其传递给存储库来执行过滤,从而修改SQL并限制数据库工作。

到目前为止,它似乎运行得非常好,并且“感觉”正确,因为我的逻辑非常牢固地在服务层中,而存储库仅执行基本的CRUD操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接