2009-09-21 2 views
3

고객의 목록을 표시해야하지만 이름 만 표시하고 목록 컨트롤의 이름에 키를 연결하려는 경우를 가정 해 보겠습니다.리포지토리 <T>에서 데이터의 하위 집합을 반환 할 수 있습니까?

전체 고객 목록 및 모든 속성을 검색하는 데 비용이 많이 듭니다. 이 시나리오에서는 필요한 속성 (이 경우 Id 및 Name)을 사용하여 다른 클래스를 만드는 것이 더 좋을까요?

기본 구현은 다음과 같을 수 있습니다 :

public class Customer { 
    public int Id { get; set; } 
    public string Firstname { get; set; } 
    public string Lastname { get; set; } 
    public int Age { get; set; } 
    ..... 
} 

public class CustomerListView { 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

public interface IRepository<T> { 
    public T Find(int id); 
    public IEnumerable<T> FindAll(); 
    .... 
} 

public class Repository<T>: IRepository<T> { 
    .... 
} 

public class CustomerRepository: Repository<Customer> { 
    public IEnumerable<CustomerListView> FindAllListView(); 
} 

것은이 방법이 적합 할 것인가? 다른 옵션은 무엇입니까?

답변

1

당신이 일을 더 비용이없는 것보다 대신를 IEnumerable의 수익으로 된 IQueryable를 사용하는 경우 :..

CustomerRepository은() GETALL() 찾기 (1) 데이터를 요청할 때까지 AsQueryable 실제로 실행되지 않기 때문입니다.

SELECT를 .... ID = 1의 대신

모든것 어디서 ....에서 : 즉 LINQ는 그것을을 최적화 할 것을 의미한다. ID가 = 1

가에 대한 설명이 게시물을 참조하십시오 WHERE 찾기 : 익명 클래스를 만들 수 있습니다 와이어를 통해가는 데이터를 좁힐 학습과이 방법을 사용

Why use AsQueryable() instead of List()?

을 당신이 원하는 단지 무엇을 . 그러면 LINQ에 의해 생성 된 쿼리가 최대한 최적화됩니다.

+0

이것은 흥미로운 생각이며, 나는 고려하지 않았습니다. 내 저장소를 LINQ에 연결하는 것 외에도 이것을 피할 수있는 다른 이유가 있습니까? 저는 항상 저장소의 책임이 도메인 객체에 대한 액세스를 제공하는 것이라고 생각했습니다. 어느 쪽이든, 내가해야한다면 '순수한'DDD에서 벗어나도 상관 없으므로이 제안을 살펴볼 것입니다. – Joepro

+0

LINQ는 C#의 핵심 기능이므로 걱정할 필요가 없습니다. 이 디자인 패턴은 종종 Repository로 보이지만, 무엇보다 ActiveRecord가 더 많습니다. 내가 자주하는 일은 데코레이터 패턴을 사용하고 추가 필터링을 수행하기 위해 확장 메서드를 유형에 두는 것입니다. –

1

데이터베이스에서 목록 양식을 검색해야하는 경우 제안서가 의미가 있지만 Linq 및 익명 형 솔루션을 살펴볼 것입니다.

고객 목록이 이미 메모리에 있으면 비용 절감 효과가 없습니다.

+0

네, 맞습니다. 데이터베이스에서 데이터를 가져와야한다고 언급 했어야합니다. – Joepro

2

이러한 목표를 달성하기 위해 개요를 표시하는 데 필요한 속성 만 포함하는 CustomerView와 같은 간단한 'View'클래스를 만듭니다.

My Repository에는 이러한 CustomerView 개체의 컬렉션을 반환하는 메서드가 있습니다.

저는 주로 내 프로젝트에서 NHibernate를 사용합니다. Nhibernate는 '투영법'을 사용할 수있게합니다. 내 저장소에서 수행하는 작업은 다음과 같습니다. (아래의 코드는 단지 의사 코드이며 컴파일되지 않습니다.) 사실

public IList<CustomerView> GetAllCustomers() 
{ 
    ICriteria crit = _session.CreateCriteria (typeof(Customer)); 

    crit.AddProjection (...); 

    crit.SetResultTransformer (new EntityToBeanTransformer(typeof(CustomerView)); 

    return crit.ToList(); 
} 

, 그것은이 내려 온다 : 나는 고객을 조회한다 나의 O/R 매퍼를 이야기하지만, 유형 'CustomerView'의 실체를 반환해야 함. 프로젝션의 정의에서 Customer 클래스의 어떤 속성이 CustomerView 클래스의 속성에 매핑되는지 정의합니다. 그런 다음 O/R 매퍼는 매우 간단하여 CustomerView 클래스를 채우는 데 필요한 필드 만 검색하는 매우 간단한 쿼리를 생성합니다.당신이-NHibernate에 Linq에를-사용하여 닛산과 프레데릭 (익명의 종류와 NHibernate에)에 의해 사용되는 기술을 결합 할 수

SELECT customerid, customername FROM tblCustomer 
+0

NHibernate 사용을 고려하지 않았습니다. 제안 해 주셔서 감사합니다. – Joepro

+0

내 요점은 NHibernate (훌륭한 도구이므로 도움이 될지라도)를 사용해야한다고 제안하는 것이 아니었지만, 개요를 표시하기 위해 '바보 (dumb)'CustomerView 유형을 사용하는 것이 완벽하게 중요합니다. 고객의 –

0

: 는 예를 들어, 실행되는 쿼리는 다음과 같이 간단 할 수 있습니다.

Bill Wagner의보다 효과적인 C#의 항목 # 31 "익명 유형을 사용하여 범위 유형 제한"이라고 말하면 동의합니다. BTW, 나는 전체 책을 추천한다.

관련 문제