2012-05-11 4 views
0

Users 컬렉션이있는 Sites 세트가 있습니다. 주어진 질문에 대해 User을 방문하여 쿼리를 재정의해야 할 때마다 DRY 교장을 위반하는 것으로 나타납니다. site. 그 쿼리가 내가 원하는 반환공통 쿼리를 사용하여 엔터티 모델을 확장 할 수 있습니까?

from site in Context.Sites 
where site.ID == 99 
select new { 
    ID = site.ID, 
    Name = site.Name, 
    URL = site.URL, 
    LastVisitedUser = site.Users.OrderByDescending(u => u.LastVisited).Select(u => new { 
     ID = u.ID, 
     Username = u.Username, 
     Email = u.EmailAddress 
    }) 
    .FirstOrDefault() 
} 

을, 그러나 나는 나 자신이 내가 사이트를 선택 해요로이 같은 여러 장소에서 LastVisitedUser에 대한 선택 반복 찾을 :

예를 들어, 내 쿼리는 다음과 같이 보일 수 있습니다 내 다양한 ​​ViewModels을 채우는 다른 방법.

public partial class Site { 
    public LastVisitedUser { 
    get { 
     var query = from user in Users 
        where user.SiteID == this.ID 
        orderby user.LastVisited descending 
        select user; 
     return query.FirstOrDefault() 
    } 
    } 
} 

을 이러한 방식으로, 나는이 사이트가이 속성을 잡아 아주 사소한 것을 선택하고 때마다 :

그래서, 나는 단순히 그래서 같은 속성을 사용하여 내 사이트 실재물 클래스를 확장하는 것이라고 생각했다. 이 거의 작품 그러나, 내 UserViewModel 속성 내 반환의 LastVisited 속성에 엔터티 사용자를 할당하는 시도가 붙어있어 User 내 ViewModel 버전으로 투영하는 방법에 대한 분명한 방법없이.

아마도 예를 들어 설명 할 수 있습니다. 내가 성취하려고하는 것은 다음과 같을 것이다 :

from site in Context.Sites 
where site.ID == 99 
select new SiteViewModel { 
    ID = site.ID, 
    Name = site.Name, 
    URL = site.URL, 
    LastVisitedUser = site.LastVisitedUser <--- NOTE  
} 

참고 = 이것은 나의 실패 원인이다. LastVisitedUser은 서브 모델이 User 인 ViewModel입니다.

나는 올바른 방식으로이 문제를 다루고 있습니까? 제가하려는 일을 성취 할 수 있습니까, 아니면 끔찍하게 잘못 생각합니까? 나는이 문제를 싫어하고 다른 사람들과 마주 친다.

감사합니다.

+0

컨트롤러에서 호출되는 이러한 메서드 또는 이러한 쿼리가 필요한 계층은 무엇입니까? – RoelF

+0

내 저장소에 있습니다. 내 컨트롤러는 IEnumerable 변형 또는 구체적인 개체를 다루고 있습니다. – BradBrening

답변

3

편집 : 이전 대답이 올바르지 않습니다. 탐색 속성에서 확장 메서드를 사용할 수는 없지만 전체 Site 투영에 대한 확장 메서드를 계속 만들 수 있습니다.

그냥 간단한 재사용 가능한 확장 메서드를 작성 : 이제

public static IQueryalbe<SiteModel> GetSiteModels(this IQueryable<Site> query) 
{ 
    return query.Select(site => new SiteModel { 
        ID = site.ID, 
        Name = site.Name, 
        URL = site.URL, 
        LastVisitedUser = site.Users 
              .OrderByDescending(u => u.LastVisited) 
              .Select(u => new LastVisitedUser { 
               ID = u.ID, 
               Username = u.Username, 
               Email = u.EmailAddress 
              }}); 
} 

당신이 당신의 이전 쿼리에서 그 확장을 사용할 수 있어야합니다을 :

Context.Sites.Where(site => site.ID == 99).GetSiteModels(); 
재산이 표시되지 않기 때문에

귀하의 예는 작동하지 않습니다 Linq - 엔터티.

+0

필자는이 작업을 시도해 봤는데도 계속 오류가 발생합니다. EntityCollection 에는 GetLastUsers()에 대한 정의가없고 EntityCollection 유형의 첫 번째 인수 인 을 수락하는 확장 메서드가 없습니다.심지어 네임 스페이스 나 다른 것을 엉망이 아닌지 확인하기 위해 저장소 클래스 내에 확장 메서드를 배치했습니다. 내가 놓친 게 있니? – BradBrening

+0

네가 맞다. 네비게이션 속성에서 투영법으로 표현 방법을 사용할 수 없기 때문에 효과가 없다. 전체 사이트 투영에 대한 확장 방법을 만들어야합니다. –

0

다른 확장을 사용하여 일반적인 쿼리를 재사용한다는 의미라면 일부 기본 쿼리를 작성하고 다른 결과와 일부 람다 식을 얻으려고합니다. 프로파일 링하면 기본 쿼리에서 IQuerable을 반환하는 DB에 대한 쿼리가 하나만있는 것을 볼 수 있습니다.

관련 문제