2016-11-10 12 views
1

IRepository 패턴을 사용하여 데이터 계층을 구현했습니다.서비스 계층에 대한 Entity Framework 확장자 표시

public virtual IQueryable<TEntity> Queryable() 
{ 
     return dbSet; 
} 

나는 또한 필터링 예를 들어 공급이 메소드를 호출 서비스 계층이 : 이러한 방법 중 하나는 IQueryable 반환 지금까지 너무 좋아

public User GetByName(string name) 
{ 
    return _repository.Queryable() 
     .Where(a => a.Name == name) 
     .ToList(); 
} 

을, 엔티티 프레임 워크는 데이터 만에서 참조 계층에서, 서비스 계층은 이것에 대해 아무 것도 모른다.

  1. 사용

그래서 지금 내 서비스 방법은 다음과 같이 보이는 Include 방법

  • 사용 ToListAsync() 방법 :

    지금, 그러나 나는 두 가지 추가 작업을 수행 할

    public async Task<User> GetByName(string name) 
    { 
        return await _repository.Queryable() 
         .Where(a => a.Name == name) 
         .Include(x => x.Pets) 
         .ToListAsync(); 
    } 
    

    이제 문제는 Include()ToListAsync()은 모두 인 System.Data.Entity 네임 스페이스에 있습니다.

    내 서비스 계층 내에서 EF를 참조하고 싶지는 않지만 신경 쓰지 않아야합니다. 그러나이 문제를 해결하는 방법을 알지 못하고 아키텍처를 깨끗하게 유지할 수 없습니다. 내가 볼 수있는 유일한 해결 방법은 다음과 같습니다

    1. IRepository<User>' and handles the two additional methods required. The service will then take use an instance of this rather than IRepository` 랩 데이터 층 (UserData)에 새 클래스를 추가 계층에게
    2. 서비스를 제공하는 엔티티 프레임 워크를 추가합니다.

    모범 사례를 준수하면서 어떻게 해결할 수 있을지 제안 해주세요.

  • +1

    비즈니스 레이어가 자체 쿼리를 작성할 수있는 호출을 노출하려는 경우 EF 추상화의 요점을 이해하지 못합니다. 그것은 저장소가 나에게 쓸데없는 것 같은 느낌을 갖게합니다. 실제로 질문과 관련이 없지만 논리가 무엇인지 궁금합니다. – Jonesopolis

    +0

    'Include' 부분이 정말로 저장소에 있어야한다고 생각합니다. 본질적으로 리포지토리는 개체 그래프 측면에서 무엇을 반환해야하는지 알고 있어야하며 이러한 작업은 모든 유스 케이스의 비즈니스 요구를 지원해야합니다. 'ToListAsync'가 EF 외부에 있다면 좋을 것 같습니다. EF 밖에서도 이해가되는지 알기 위해 구현에 대해 충분히 알지 못합니다. – David

    +0

    "최상의 실습"을 제외하고 리포지토리를 정확히 사용하는 이유는 무엇입니까? 어쩌면 결과 또는 뭔가를 캐시하려고 할 것입니다. – Evk

    답변

    0

    Include 및 ToListAsync는 EF에 있으므로, EF 서비스에 보관해야합니다.

    System.Entity에 대한 참조를 제공하지 않고도 액세스 할 수있는 유일한 방법은 고유 한 프록시 메소드를 만드는 것입니다. 하루가 끝나면 EF가 할 수있는 모든 것을 액세스 할 수 있는지 확인하기보다는 응용 프로그램이 요구하는 수준을 코딩해야합니다.

    EF를 처리 할 때 서비스/컨텍스트 계층, 저장소 계층, 그리고 EF 기술을 추상화하는 클라이언트 계층을 작성합니다. 이것은 다른 devs/사용자에 의한 사용자입니다. 그래서 그들은 EF쪽에 너무 많이 노출되지 않습니다. 방금 애플 리케이션에 필요한 무엇을 운동하고 그냥 아무것도 할 더 많은 방법을 구현합니다. System.Entity의 기능을 DAL 이상으로 가져 오는 점은 거의 없으며 클라이언트 수준에서 추상화되어야합니다.

    내 서비스/컨텍스트 계층을 응용 프로그램의 다른 부분과 멀리두고 싶다면 모델을 복제해야한다는 것이 싫어합니다. 이 문제를 해결하기 위해 DI를 사용하여 EF 모델을 찾고 DI 컨테이너를 통해 전달하는 모델 공장이 있습니다. 단지 내가 만든 각 모델에 인터페이스를 추가해야한다는 것을 의미합니다. 더 이상.

    1

    모범 사례를 기반으로 저장소 계층에서 EF를 추상화하려는 것으로 알고 있습니다.하지만 유스 케이스 (여기에서 가장 중요한 질문)는 모순이다. EF가 제공하는 모든 것을 서비스 레이어에 노출하고 싶다.

    이 저장소의 책임에 대한 엄격한 정의가 필요한 것 같습니다. IQueryable을 반환하는 경우 EF를 전혀 감쌀 때 어떤 이점이 있습니까? 실제 운영 환경에서 사용할 다른 저장소 구현이 있습니까? 그렇다면 IQueryable을 노출 할 때 두 repo 유형이 올바른지 확인하는 것이 매우 어려울 것입니다. 이것은 현재 당신이보고있는 고통의 포인트입니다.

    제 생각에는 리포지토리가 데이터를 얻는 방법을 정의해야합니다. 실제 모델을 반환하는 GetAllUsers과 같은 간단한 호출을 노출해야합니다. 비즈니스/서비스 계층이 데이터를 얻기 위해 자체적 인 방법을 정의하게 만들면 저장소가 중복 될 수 있습니다.