简体   繁体   English

服务应具有多少个GET方法?

[英]How many GET methods a service should have?

What are the best practices for writing a service layer methods that retrieves data from repository? 编写从存储库检索数据的服务层方法的最佳实践是什么?

Let's say we have two models: Team and User (user is part of a team): 假设我们有两种模型: 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; }
}

If I want to write service to retrieve user data from repository by various conditions, do I have to write multiple methods to get a user eg getAll , getAllByName , getAllActiveByName , getAllActiveByTeamId , getAllActiveByNameAndTeamId , etc? 如果我想编写服务以通过各种条件从存储库中检索用户数据,是否需要编写多种方法来获取用户,例如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);
}

These are just simple examples but in real life we can end up having tens of service methods for different scenarios, when models are more complex. 这些只是简单的示例,但是在现实生活中,当模型更加复杂时,我们最终可能会为不同的场景使用数十种服务方法。

Or maybe it is better to have one GetBy method that will return users based on the provided filter? 还是最好有一种GetBy方法,该方法将根据提供的过滤器返回用户? I use Generic Repository Pattern and I could use GetBy method when implementing GetBy service method: 我使用通用存储库模式,实现GetBy服务方法时可以使用GetBy方法:

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

Having this I would not have to write tens of "duplicated" methods for all the scenarios. 有了这个,我将不必为所有场景编写数十个“重复的”方法。 Then it would be controller responsibility to set the filter: 然后由管理员负责设置过滤器:

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

Any thoughts on that? 有什么想法吗?

I'm of the opinion that you should have as many query methods as you have scenarios. 我认为您应该拥有与场景一样多的查询方法。

In that way you can optimize individual queries by for example using a precalculated view. 这样,您可以通过例如使用预先计算的视图来优化单个查询。 Some of your queries might use eager loading, other might use lazy loading... 您的某些查询可能使用紧急加载,其他查询可能使用延迟加载...

Also, if you always return IQueryable how are you going to test it? 另外,如果您始终返回IQueryable ,您将如何对其进行测试? Your service will have only one method GetAll and is so anemic that you can just get rid of it and use repository directly in the controller. 您的服务只有一种方法GetAll而且太GetAll ,您可以删除它并直接在控制器中使用存储库。

Another argument against GetAll is that any one can execute any query in the UI! 反对GetAll另一个论点是,任何人都可以在UI中执行任何查询!

Consider reading about CQRS. 考虑阅读有关CQRS的文章。

Or maybe it is better to have one getAll method that will return only active users and then use lambda expression in the controller? 还是最好有一个getAll方法,该方法仅返回活动用户,然后在控制器中使用lambda表达式?

No. This kind of query will be good only for static data that too in-memory. 否。这种查询仅适用于内存中过多的静态数据。 Say you have some application level data and it is not going to change for certain time, then instead of querying it everytime, you getall for first time and then put in local server cache. 假设您有一些应用程序级别的数据,并且在一定时间内不会更改,那么您不必每次都查询它,而是第一次获取全部,然后放入本地服务器缓存中。 Then use it for next simultaneous requests. 然后将其用于下一个同时请求。 But this approach is not going to for heavily changing dynamic data. 但是这种方法不适用于大量更改的动态数据。 Also performance of this query depends on number of records it is returning, so sometimes it might give very bad performance. 此查询的性能还取决于它返回的记录数,因此有时它的性能可能会很差。

do I have to write multiple methods to get a user eg getAll, getAllByName, getAllActiveByName, getAllActiveByTeamId, getAllActiveByNameAndTeamId, etc? 我必须编写多种方法来获取用户,例如getAll,getAllByName,getAllActiveByName,getAllActiveByTeamId,getAllActiveByNameAndTeamId等吗?

Thats better. 那更好。 This approach will give you load on demand freedom, that means load necessary data when it is required, instead of getting all data and discarding it. 这种方法将为您提供按需加载的自由,这意味着在需要时加载必要的数据,而不是获取所有数据并丢弃它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM