1

이 현물 THIS에 질문을 수행한다.eager loading/"사용자 정의 유형 선택"을 포함하는 "Include"를 사용 하시겠습니까?

나는 같은 문제에 대해 가지고 있지만,이 솔루션은 나를 위해 100 % 작동하지 않습니다.
나는 같은 쿼리를 다음과 같은 : 나는 쿼리하지 않는

item = db.Categories 
     .Include(i => i.AccessRight.Roles).Include(i => i.AccessRight.Permissions) 
     .Select(i => new ContentItemWithRevision<Category, ContentRevision>() 
      { 
       Item = i, 
       AccessRight = i.AccessRight, 
       Roles = i.AccessRight.Roles, 
       Permissions = i.AccessRight.Permissions, 
       Revision = i.Revisions.OrderByDescending(r => r.DateCreated).FirstOrDefault() 
      }) 
     .FirstOrDefault(c => c.Item.Id == id); 

AccessRight, Roles 및 "트릭"쿼리에서 Include들과 열망 로딩에 추가 된 경우 선택에 Permissions는 무시됩니다 entity type. 내가 whished로

는하지만이 작동하지 않습니다. item.Item.AccessRightSelectAccessRight = i.AccessRight으로로드되며 item.Item 만 전달하지만 내 item.Item.AccessRight.Rolesitem.Item.AccessRight.Permissions은 전달되지 않습니다 (단, item.Rolesitem.Permission이 올바르게로드 됨).
는 그래서이 "트릭은"전용 "한 단계"작동 않는 것 같다.

이 문제를 해결하는 방법이 있나요? 이 IMO 최고의 솔루션이 될 것 같은
방법은 Include 작업을 할 EF의 새로운 버전으로 지금이 있습니까?
적어도 "여러 수준"으로 속임수 작업을 할 수 있습니까? 나는 순간에 작업을 얻을 수있는

유일한 해결책은 item.Item하지만 전체 item을 통과 item.Item.AccessRight.Roles 대신 item.Roles를 사용하지 않는 것입니다,하지만 그는 알고 어떤 용도 item.Item.AccessRight.Roles 아니므로 때 충돌로이 (매우 직관적되지 않습니다 문제의) 그리고 내 응용 프로그램을 통해 몇 가지 변경 사항이 필요합니다.
또한 Select 다음에 Include을 사용해 보았습니다.하지만 Select 이후에 예외가 생겼으므로 더 이상 entity type이 없습니다. 난 그냥 (이 많은이 될 수있는) 내 Category 그것의 최신 Revision 및 모든 수정을 선택합니다
:

아마 또한 내 기본 문제에 대한 완전히 다른 솔루션이 있습니다. 내 사용자 지정 형식없이이를 수행 할 수있는 솔루션이 있으면 해당 솔루션을 사용해도됩니다.

UPDATE :
이 내 DB의 단순화 된 모델입니다 :
enter image description here
그래서 AccessRights:RolesAccessRights:Permissions에 대한 Category:Revisions에 대한 1:n, 1:1Category:AccessRightn:m있다.

다음 쿼리는 작동하지만 모든 버전을 얻을뿐 아니라 최신 일 것입니다 : 이제 질문을 업데이트 한 것을

var category = db.Categories 
        .Include(i => i.AccessRight.Roles) 
        .Include(i => i.AccessRight.Permissions) 
        .Include(i => i.Revisions) 
        .FirstOrDefault(i => i.Id == id); 

답변

1

난 당신과 할 여부, 그리고 왜 할 수 있고 무엇을해야 하는지를 설명 할 수 있습니다.당신의 작업 쿼리에서

당신은 열심히로드 된 모든 관련 탐색 속성 (AccesRight.Roles, AccesRight.PermissionsRevisions)로, 데이터베이스에서 전체 엔티티 (Category)을 취득하고 있습니다. 지금까지 너무 좋은 :

var category = db.Categories 
       .Include(i => i.AccessRight.Roles) 
       .Include(i => i.AccessRight.Permissions) 
       .Include(i => i.Revisions) 
       .FirstOrDefault(i => i.Id == id); 

그러나 이제 요구 사항은 Revisions 컬렉션의 마지막 버전을로드하는 것입니다. 그렇게했다면 속임수를 쓰게됩니다 : 의미 상 category.Revisions은 "이 카테고리의 모든 개정판"입니다. 이 속성을 사용하여 마지막 버전 만로드 한 경우 해당 의미를 깨뜨릴 수 있습니다. 그렇다고해도 가능하지만 권장하지는 않습니다. 그러나, 그것은 하나의 쿼리를 사용하여 수행 할 수 없습니다 : 그것은 모든 관련 요소를로드가 완료,하지만 Revisions하고 명시 적으로 개정을로드하지만, 필터링을,과 같이해야합니다 : 이제

ctx.Configuration.LazyLoadingEnabled = false; 

var catWithRev = ctx.Categories 
       .Include(c => c.AccessRight.Roles) 
       .Include(c => c.AccessRight.Permissions) 
       //.Include(c => c.Revisions) -- not eagerly loaded 
       .FirstOrDefault(i => i.Id == id); 

// Explicitly load the filtered revisions 
ctx.Entry(catWithRev).Collection(cwr => cwr.Revisions).Query() 
       .OrderByDescending(r => r.DateCreated).Take(1) 
       .Load(); 

, 당신은 무엇을 당신은 원했지만 다음을 고려하십시오 :

  • 지연로드를 비활성화해야합니다. 그렇지 않다면, 당신의 성품은 게으름으로로드 될 수 있습니다. 모든 개정판을 속성에 가져올 수 있습니다.
  • 모든 개정판을 포함해야하는 컬렉션의 마지막 개정 본 만 가지고 있기 때문에 의미 상으로 "엉터리"입니다.

은 그래서 다음과 같이 관련된 모든 탐색 속성, 카테고리를 보유하는 객체 있지만, 수정, 마지막 개정을 만드는 것이 훨씬 더 좋을 것이다 : 이런 식으로

var catWithRev = ctx.Categories 
       .Include(c => c.AccessRight.Roles) 
       .Include(c => c.AccessRight.Permissions) 
       //.Include(c => c.Revisions) 
       .Select(c => new 
       { 
        Category = c, 
        LastRevision = c.Revisions 
         .OrderByDescending(r => r.DateCreated) 
         .FirstOrDefault() 
       }) 
       .FirstOrDefault(i => i.Id == id); 

, 모든 데이터가 단일 쿼리에로드되고 의미 상으로 정확합니다. 샘플 코드에서와 같이 익명 형식을 사용하거나 이에 대한 클래스를 만들 수 있습니다.

(참고 :이 코드를 테스트하고있다) 귀하의 의견

+0

감사합니다. '일단 당신이 일하면'- 그것이/작동하고 있습니다. 위의 코드로 변경했는데 그 이유는 현재 개정판 만 포함 되었기 때문에 모든 개정판을 필요로하지 않고 두 버전을 하나의 쿼리로 결합 할 수 없었기 때문입니다. 나중에 "Include"를 "어떻게 든 말하지만"나중에 지정해야한다고 필터링 할 수 있습니까? – ChrFin

+0

문제를 이해하는 것은 매우 어렵습니다. 표시중인 쿼리에서 포함이 작동하지 않아야합니다 (일대 다에서 선택을 사용하지 않는 것 같습니다). 귀하의 DB 구조, 그리고 귀하가 얻은 것, 귀하가 귀하의 질의에 누락 된 부분을 알지 못합니다. 다시 단어를 추가하고, 추가 정보를 추가하고, 시도한 검색어의 샘플과 문제점을 보여 주어야합니다. 그들과 함께. BTW는 때때로 체인 된 함수 대신 SQL 같은 구문을 사용하여 도움을 줄 수 있습니다. – JotaBe

+0

나는 약간의 세부 사항으로 질문을 업데이트했다. ... – ChrFin