2010-08-05 2 views
2

ASP.NET MVC 2 및 Entity Framework를 사용하여 첫 번째 웹 응용 프로그램을 작성하는 중입니다. 저장소 패턴을 사용하고 있습니다. 스택 오버플로 및 다른 웹 사이트에서 수집 한 정보를 통해 도메인 모델 당 하나의 컨트롤러와 집계 루트 개체 당 하나의 리포지토리가 있다고합니다.ASP.NET MVC/Entity Framework : 집계 루트 리포지토리를 통해 집계 개체에 액세스

내가 가지고있는 질문은 집계 루트 저장소를 통해 비 루트 집계 개체에 액세스해야하는 방법입니다. 예제에서는 고객 모델과 보트 모델이 있습니다. 보트는 고객에 대한 FK 참조로만 존재할 수 있으며 보트는 고객의 컨텍스트 내에서 참조되어야합니다. 이로 인해 나는이 두 객체의 집합체가 있고 그 고객이 루트라는 것을 알게되었습니다.

지금 내 보트 컨트롤러에서 나는 편집 작업 방법이 있습니다

public class BoatsController : Controller 
{ 
    private ICustomersRepository customersRepository; 
    public BoatsController(ICustomersRepository customersRepository) 
    { 
     this.customersRepository = customersRepository; 
    } 
    public JsonResult Edit(int id, FormCollection collection) 
    { 
     var boat = customersRepository.GetBoat(id); 
     // Update boat 
    } 
} 

내 질문에 내가 저장소에서 보트 개체를 검색하려면 어떻게입니까?

public class SQLCustomersRepository : ICustomersRepository 
{ 
    DatabaseEntities db = new DatabaseEntities(); 

    public Boat GetBoat(int id) 
    { 
     return db.Boats.SingleOrDefault(x => x.ID == id); 

     // OR 

     return db.Customers.Where(x => x.Boats.Any(y => y.ID == id) 
          .Select(x => x.Boats.FirstOrDefault(y => y.ID == id); 
    } 
} 

Customers Repository에서 db.Boats를 참조해도됩니까? 가장 깨끗한 것으로 보이지만 FakeCustomersRepository를 변경하여 고객 및 보트 목록을 보유해야합니다.

db.Customers를 통해 Boat에 액세스하는 것이 더 합당한 것 같았지만 LINQ 쿼리에서 반복적으로 Boat 개체 하나를 반환하는 방법을 찾을 수 없었습니다. 실제로는 나와 잘 어울리지 않았습니다.

나는 아직도 배울 것이 많다는 것을 안다. 나는 올바른 방향으로 나를 가리킬 수 있기를 희망한다.

감사합니다.

답변

1

필자는 추상적 인 인터페이스와 모델이 아니라 구현 세부 사항에 대해 이야기하고 있다고 생각합니다. 귀하의 인터페이스는 다음과 같이 보인다 :

public interface ICustomersRepository 
{ 
    //... other methods 
    Boat GetBoat(int id); 
    //... other methods 
} 

이 같은 모델 :

public class Customer 
{ 
    //... other stuff 
    ICollection<Boat> Boats; // or another collection type 
    //... other stuff 
} 

나는 내 의견은 당신의 SQLCustomersRepository과에 대해 완전히 다르게 ICustomerRepository을 구현하기 위해 어떤 디자인의 규칙 위반 아니다 FakeCustomersRepository을 찾고 기본 데이터 저장소와 관련하여 최적의 구현을 찾으십시오.

당신은 내가 확실히이 활용할 것이다 당신의 SQL-DB에서 보트 테이블에 기본 키가 첫 번째 옵션을 구현하는 것 때문에 : return db.Boats.SingleOrDefault(x => x.ID == id);

를하지만의 보트 컬렉션이 할 필요는 없습니다 당신의 FakeCustomersRepository. 고객 목록을 갖고 테스트 보트를 사용하여 각 고객의 보트 컬렉션을 채우는 것이 더 쉬울 경우, 왜 안됩니까? 이 경우 FakeCustomersRepository에 구현 된 GetBoat 구현은 설명 된 두 번째 LINQ 쿼리로 구현 될 수 있습니다.

MVC의 단위 테스트는 특정 리포지토리 구현이지만 비즈니스 논리를 테스트하지 않으므로 비즈니스 작업은 다양한 도메인 개체 및 리포지토리 메서드 호출의 체인입니다. 단일 저장소 메소드가 수행해야하는 작업을 수행하는 경우 (예 : GetBoat이 실제로 올바른 ID로 보트를 리턴하는 경우) 나중에 데이터베이스 호출이 올바로 작동 함을 입증하는 차후 통합 테스트의 문제입니다.

+0

답장을 보내 주셔서 감사합니다. 나는이 새로운 때부터 나는 내가 몇 가지 기본적인 규칙이나 어떤 것도 위반하지 않았는지 확인하기를 원했다. –

0

왜 보트 저장소가 없습니까?

Boat가 AggRoot 인 경우 보트 용으로 별도의 저장소가 있어야합니다.

+0

보트는 특정 고객의 컨텍스트 외부에서 절대 참조되지 않습니다. 나는 이것이 고객을 보트와 고객의 집합체로 만들었다 고 확신했다. 아마도 집계 루트를 올바르게 정의하는 방법을 이해하지 못하고 있습니까? –