服务应该有多少GET方法?

时间:2014-01-29 10:55:57

标签: c# asp.net-mvc asp.net-mvc-4

编写从存储库中检索数据的服务层方法的最佳做法是什么?

假设我们有两个模型:TeamUser(用户是团队的一员):

public class User {
    public int Id { get; set; }
    public string Name { get; set; }
    public int TeamId { get; set; }
    public virtual Team Team { get; set; }
    public bool Active { get; set; }
}

public class Team {
    public int Id { get; set; }
    public string Name { get; set; }
    public bool Active { get; set; }
}

如果我想编写服务以通过各种条件从存储库中检索用户数据,我是否必须编写多种方法来获取用户,例如getAllgetAllByNamegetAllActiveByNamegetAllActiveByTeamIdgetAllActiveByNameAndTeamId等?

public IEnumerable<User> GetAll()
{
    return _repository.GetAll();
}

public IEnumerable<User> GetAllActiveByName(string name)
{
    return _repository.GetBy(u => u.Name == name && u.Active);
}

public IEnumerable<User> GetAllActiveByNameAndTeamId(string name, int teamId)
{
    return _repository.GetBy(u => u.Name == name && u.Active && u.TeamId == teamId);
}

这些只是简单的例子,但在现实生活中,当模型更复杂时,我们最终可能会为不同的场景提供数十种服务方法。

或者最好让一个GetBy方法根据提供的过滤器返回用户?我使用Generic Repository Pattern,我可以在实现GetBy服务方法时使用GetBy方法:

public IEnumerable<User> GetBy(Expression<Func<User, object>>filter )
{
    return _usersRepository.GetBy(filter);
}

有了这个,我不必为所有场景编写数十个“重复”方法。 然后设置过滤器是控制器的责任:

public ViewResult Index(int teamId = 0){
    //[...]
    var users = _usersService.GetBy(u => u.IsActive && u.teamId == teamId);
    //[...]
}

对此有何看法?

2 个答案:

答案 0 :(得分:1)

我认为您应该拥有与场景一样多的查询方法。

通过这种方式,您可以通过例如使用预先计算的视图来优化单个查询。 您的某些查询可能会使用预先加载,其他人可能会使用延迟加载...

另外,如果您总是返回IQueryable,您将如何测试它?您的服务只有一个方法GetAll并且非常贫乏,您可以直接删除它并直接在控制器中使用存储库。

针对GetAll的另一个论点是,任何人都可以在UI中执行任何查询!

考虑阅读CQRS。

答案 1 :(得分:0)

  

或者最好只使用一个只返回的getAll方法   活跃用户,然后在控制器中使用lambda表达式?

没有。这种查询仅适用于内存过多的静态数据。假设您有一些应用程序级数据并且它不会在一定时间内更改,那么不是每次都查询它,而是首次获取然后放入本地服务器缓存。然后将其用于下一个同时请求。但是这种方法不适用于大量改变动态数据。此查询的性能也取决于它返回的记录数,因此有时可能会产生非常糟糕的性能。

  

我是否必须编写多种方法来获取用户,例如得到所有,   getAllByName,getAllActiveByName,getAllActiveByTeamId,   getAllActiveByNameAndTeamId等?

好多了。这种方法可以为您提供按需加载,即在需要时加载必要的数据,而不是获取所有数据并将其丢弃。