2014-01-29 1 views
1

리포지토리에서 데이터를 검색하는 서비스 계층 메서드를 작성하는 모범 사례는 무엇입니까?서비스에 몇 가지 GET 메소드가 있어야합니까?

의 우리는 두 가지 모델이 있다고 가정 해 봅시다 : 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; } 
} 

나는 다양한 조건에 의해 저장소에서 사용자 데이터를 검색하는 서비스를 작성하려는 경우, 내가해야합니까 사용자를 얻는 여러 가지 방법을 작성하십시오. getAll, getAllByName, getAllActiveByName, getAllActiveByTeamId, getAllActiveByNameAndTeamId 등?

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 제공된 필터를 기반으로 사용자를 반환하는 방법을 사용하는 것이 더 좋을 수도 있습니다. 나는 일반 저장소 패턴을 사용하고 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); 
    //[...] 
} 

어떤 생각 : 는 그런 다음 필터를 설정하는 컨트롤러의 책임 것입니까?

+0

에는 "일반 저장소 인터페이스 C#"에 대한 Google이 있습니다. 그것은 당신에게 당신이 필요로하는 것에 대한 아이디어를줍니다. –

+0

@WimOmbelets 일반적인 저장소 패턴을 사용하고 있으며 데이터를 검색하기 위해 저장소에서 필요한 메서드를 알고 있습니다. 질문은 데이터를 검색하는 SERVICE 계층 메서드에 대한 것입니다. 다른 의견을 읽으십시오. 오해를 피하기 위해 질문을 업데이트했습니다. –

답변

1

시나리오가있는 것만 큼 많은 쿼리 방법을 사용해야한다고 생각합니다.

이렇게하면 미리 계산 된보기를 사용하여 개별 쿼리를 최적화 할 수 있습니다. 쿼리 중 일부는 열심히로드 할 수 있고 다른 하나는 지연로드를 사용할 수 있습니다 ...

또한 항상 IQueryable을 반환 할 것입니다. 어떻게 테스트 할 예정입니까? 귀하의 서비스는 단 하나의 방법 GetAll을 가지게 될 것이며 너무 빈혈적이어서 컨트롤러에서 저장소를 직접 사용할 수 있습니다.

GetAll에 대한 또 다른 인수는 UI에서 모든 쿼리를 실행할 수 있다는 것입니다.

CQRS에 대해 읽는 것을 고려하십시오.

+0

GetAll이 서비스의 유일한 방법은 아닙니다. 비즈니스 로직을 처리하는 다른 방법이 있습니다. 내 게시물은 엔티티의 "목록"을 검색하는 메소드와 관련되어 있습니다. 어쨌든 GetAll을 사용하게 될 것이므로 제 질문은 "다른 방법을 구현해야합니까?"입니다. GetAllByThisAndThisAnd, 만약 내가 이미 GetAll을 사용할 수있을 때. 성능은 다른 방법을 쓰는 좋은 이유가 될 수 있습니다. –

0

또는 활성 사용자 만 반환하고 컨트롤러에서 람다 식을 사용하는 getAll 메서드를 사용하는 것이 좋습니다.

아니요. 이러한 쿼리는 메모리가 너무 많은 정적 데이터에만 유용합니다. 일부 응용 프로그램 수준의 데이터가 있고 특정 시간 동안 변경하지 않을 경우 매번 쿼리하는 대신 처음으로 get하고 로컬 서버 캐시에 저장하십시오. 그런 다음 다음 동시 요청에 사용하십시오. 그러나이 접근 방식은 동적 데이터를 크게 변경하지 않을 것입니다. 또한이 쿼리의 성능은 반환되는 레코드 수에 따라 다르므로 가끔 성능이 저하 될 수 있습니다.

사용자를 얻으려면 여러 가지 방법을 써야합니다.getAll, getAllByName, getAllActiveByName, getAllActiveByTeamId, getAllActiveByNameAndTeamId 등?

그게 더 좋습니다. 이 접근법은 모든 데이터를 가져오고 폐기하는 대신 필요한 데이터를로드하는 것을 의미합니다.

관련 문제