2010-06-19 3 views
0

한쪽에서 킬러 응용 프로그램 (ASP.NET MVC)을 작성하고 싶습니다.) 다른 측면에서 "소위"모범 사례를 계속 유지해야한다면 많은 의구심이 있습니다. 비용. 그래서 나는 디자인 질문을 가지고 있으며, 정말로 당신이 나를 도울 수 있기를 바랍니다.도메인 모델 의심

표준 블로그를 상상해보십시오. 최근 게시물 10 개를 보여주고 싶습니다. 내 데이터베이스에 표준
Posts, Categories, Tags, PostTags
테이블이 있습니다. 그래서 자연스러운 결과로, 내 도메인 Post 클래스는 다음과 같은 속성을 갖습니다.

public Category Category { get; set; } 
public virtual ICollection<Tag> Tags { get; set; } 

나는 POCO를 지원하는 EF4를 사용합니다. 그리고 표준 쿼리 데이터를로드 :

from p in context.Posts.Include("Category").Include("Tags") 
select p 

을하지만 (예를 들어와 그 2 곳) 전체 포스트 클래스를로드해야하는 이유, 때 페이지에 내가 (게시물 자체 외에) 보여주고 싶은 모든 카테고리 및 각 태그에 대한 링크이므로 필요한 모든 열은
[Categories].[Name], [Categories].[Slug], [Tags].[Name], [Tags.Slug]입니다.

전체 범주 또는 태그 인스턴스 (데이터베이스의 해당 테이블에 100 개의 열이있을 수 있음)가 필요하지 않습니다! 나는 사이트가 많은 요청을 받으면 문제가되는 것이라고 상상한다. 따라서 모든 열을로드하지 않는 것이 좋을 것입니다 (무서운 피하십시오 SELECT *).

내 도메인에 새로운 클래스를 추가 할 수 있다고 생각했습니다. ShortPost. 하지만 내 도메인이 아니라고 느낍니다. Post가 모델입니다. ShortPost는 ... 글쎄요, 완전한 Post의 일부입니다. 게다가이 ShortPost는 View를 기쁘게하기 위해 modyfying/domain (Model) 조정과 같은 느낌을줍니다.

총계 : 전체 모델 인스턴스를로드해야 할 때 뷰 측면에서 전체 개체가 필요하지 않습니까? 선호하는 솔루션/방법/기타에 대해 알려주실 수 있습니까?

답변

1

로드 전체 도메인 모델 - 그런 식으로 캐시에 전체 개체를 캐시 할 수 있습니다.

캐시에 부분적으로 채워진 개체를 혼동시키는 것은 혼란을 겪을 수 있습니다.

+0

OK, 그 대답입니다 ...하지만 반대 논쟁으로 저는 다음과 같이 말할 것입니다 : 전체 인스턴스 (예 : 데이터베이스의 200 열을 의미)를로드하는 것이 속도가 느려지는 것을 두려워합니다. 그리고 웹 응용 프로그램의 성능은 다음과 같습니다. 꽤 중요합니다. – Darmak

+0

캐싱에 대해 완전히 잊어 버렸습니다 ... 그 트릭을 할 것입니다. 대단히 감사합니다 개념 : – Darmak

0

은 예를 감안할 때 - 내가 함께 갈 것입니다 :

public class Post 
{ 
    public Category Category {get;set;} 
} 
public class Tag 
{ 
    public Post {get;set;} 
} 

는 당신이 필요로 정확히 태그를 조회하는 것이 훨씬 쉽게 그 방법 필요할 (당신은 사람들을 위해 태그를 쿼리 할 때 포스트 제공 태그에 대한 게시를 쿼리하는 대신 게시물을 일치 시켜서 페이지를 작성하고 필터링하는 등의 작업을 수행합니다.

내가 할 수있는 한, 나는 부모 개체 없이는 존재할 수없는 값 개체가 아니면 컬렉션을 피하는 경향이 있습니다. 내 경험을 유지하는 것이 훨씬 쉬울 것입니다.

그리고 언제든지 게시물에 대한 통계를 표시해야하는 경우 (첨부 된 태그의 수 등) - 필요한 데이터 만 사용하여 데이터의 '보기'를 사용할 수 있습니다 (표의보기와 동일). 귀하의 DB에). 조회수는 도메인 외부에 있으므로 도메인 규칙을 지키지 않아도됩니다. 그런 다음 '편집 모드'로 들어가면 전체 엔티티를로드합니다.

+0

팁은 있지만 내 질문에는 대답하지 않았습니다. 나는 단순히 (필자의보기에서) 필요하지 않은 많은 데이터를 가진 엔티티를 완전히로드하기 위해 SELECT *를 수행하는 것이 "베스트 프랙티스"의 관점에서 괜찮은지 물어볼 것이다. – Darmak

+0

짧은 대답은 그것이 달려 있다는 것입니다. Select *는 문제가있는 경우에만 문제입니다 (일반적으로 읽기 : 성능). 문제가있는 경우에만 이러한 최적화를 수행하십시오. – Goblin

+0

흠, 모든 데이터를로드하는 "예"에 대한 두 번째 투표 ... 저는 과보호하다고 생각하기 시작합니다. – Darmak

2

엔티티를 읽지 않으시겠습니까? 이것은 Command-Query Separation 패턴의 특성입니다.당신의보기 필요 [카테고리]있는 필드 만하면

. [이름], [카테고리]. [민달팽이], [태그]. [이름], [Tags.Slug]

는 그런 다음 DTO를 만드는 것이 이를 나타내고 엔터티를 투사하거나 데이터 저장소를 직접 쿼리하여 데이터를 채 웁니다.

public class PostDto 
{ 
    public string CategoryName { get; set; } 

    public string CategorySlug { get; set; } 

    public string TagName { get; set; } 

    public string TagSlug { get; set; } 

} 
+0

그래, 그것은 *를 제거합니다,하지만 PostDTO는 개념적으로 모델에 속하지 않으므로 내 리포지토리에서 DB를 쿼리하는 데 사용해서는 안됩니다? – Darmak

+0

ViewModel에 속하지만 리포지토리에서 참조하면 안됩니다. CQS에서는 ViewModel을 채우기 위해 리포지토리를 사용하지 않지만 얇은 쿼리 레이어와 리포지토리는 쓰기 작업이나 명령에만 사용됩니다. – willbt