2012-09-07 2 views
6

다음을 LINQ 문으로 변환하는 작업을 수행 할 수 있습니까?SQL 문을 LINQ-To-SQL로 변환

SELECT reports.* FROM [dbo].[ReportLists] rl 
INNER JOIN [dbo].[ReportItems] ri ON rl.Id = ri.ReportListId 
INNER JOIN [dbo].[Reports] reports ON ri.Id = reports.ReportItemId 
WHERE 
    reports.createdDate 
IN (
    SELECT 
     MAX(report_max_dates.createdDate) 
    FROM 
     [dbo].[Reports] report_max_dates 
    GROUP BY 
     report_max_dates.seedLot 
    ) 

현재 나는이에 내려 있습니다

db.ReportLists.Select(rl => db.ReportItems 
          .Where(ri => ri.ReportListId == rl.Id) 
          .Select(ri => db.Reports 
              .Where(r => r.ReportItemId == ri.Id) 
              .GroupBy(r => new { r.seedLot }) 
              .Select(g => g.OrderByDescending(x => x.createdDate).FirstOrDefault()))); 

LINQ의 문제는 위의이 제목이 변경 항목을 반환한다는 것입니다. 데이터베이스 내에서 모든 레코드의 기록을 유지합니다 (따라서 createdDate 순서의 첫 번째 레코드가 내림차순이어야합니다.) 제목 x에서 제목 y로 보고서를 변경하면 가장 최근의 레코드 만 필요할 때 두 제목 아래에 표시됩니다. 따라서 제목 y를 아래의 하나.

편집 세부의 부족에 대한 죄송합니다. 나는 (식별자 인 seedlot) 보고서에 대한 정보를 보유하고 보고서 테이블. 보고서가 수정 될 때마다 새로운 기록을 가지고 이 경우 히스토리가 유지되도록 (예전의 것을 갱신하는 것) 삽입된다.이 경우, createdDate의 최대 엔트리는 리포트가 표시 될 가장 최근의 레코드임을 나타낸다. 리포트는 타이틀 또는 ReportItem으로 그룹화된다. 이러한 리포트 아이템 제목과 관련 보고서를 보유합니다. 이러한 reportItem은 다음과 같은 ReportList에 보관됩니다. JSON을 원하는 형식으로 출력하고 ReportItems에 연결된 상태 열과 ID 만 포함 할 수 있습니다.

보고서가 제목 a에서 제목 b로 이동 된 경우, 제목 외래 키가 변경된 제목까지 링크 된 새 레코드가 입력됩니다. 이 경우 위의 주어진 LINQ는 제목 b에 대한 최신 항목 만 반환해야하는 경우 (위의 예 에서처럼) 각 ReportItem 아래에 레코드를 반환합니다. 이 이외의 LINQ 문은 createdDate에 대한 가장 최근의 레코드 만 반환합니다. 여기

public class ReportList { 
    public int Id {get;set;} 
    public string status {get;set;} 
    public List<ReportItem> {get;set;} 
} 

public class ReportItem { 
    public int Id {get;set} 
    public string title {get;set;} 
    public List<Report> {get;set;} 
} 

public class Report { 
    public int Id {get;set;} 
    public string Lot {get;set;} 
    ... Other data ... 
    public DateTime createdDate {get;set;} 
} 

감사합니다, Dman

+1

그래서 seed_lot은 이름 변경을 겪은 서로 별개의 보고서와 별개의 보고서를 구별한다는 점을 이해합니다. 즉, report_max_dates가 실행되는 한, 이름이 변경된 보고서는 실제로 별개의 (관련없는) 보고서와 다르지 않습니다. –

+0

자세한 내용을 입력하십시오. 당신이 원하는 것을 설명하십시오. 그것은 SQL 스 니펫과 잘못된 linq 쿼리에서 유추하기 어렵습니다. 그리고 한 가지 보고서의 다양한 버전이 어떻게 함께 유지되는지 설명하십시오. –

+0

업데이트 기록의 체인을 추적하여 incarnation의 seed_lot을 기반으로 한 보고서의 최신 버전 *을 가져와야하므로이 LINQ 버전을 많이 (?) 처음에 보일 수도 있습니다. . –

답변

0

데이터베이스 스키마를 일종의 평탄화로 변경하여 많은 분기를 제거했습니다.

보고서가 이제 루트이고 보고서에 첨부 된 제목 표가 있습니다.

제안에 감사드립니다.

0

나는 그것이 바로, 당신은 seedLot에 의해 최신 보고서를 원하는 이해한다면, 나는 '(뿐만 아니라 DB 구조를 모방) 내 클래스 구조입니다 D 사용 옆에 : 당신이 결과로를 포함하지 않는 경우

from r in Reports 
group r by r.CreateDate into g 
select g.OrderByDescending(r1=>r1.CreateDate).FirstOrDefault() 

당신은 왜 당신이 그들에게 통과 수에 의해, ReportItem 및 ReportList을 확신이 필요하지 않음 보고서의 탐색 속성.

+0

JSON 객체가 수신 측에서 필요에 따라 포맷되도록 ReportList 및 ReportItem이 필요합니다. 내 가장 내부 LINQ 문이 이미이 작업을 수행합니다. – DMCApps

0

아. 내가 참조. Inner Join은 ReportItems 테이블에 Id가없는 레코드를 제외하고 ReportLists 테이블에 Id가없는 ReportItems를 제거합니다. Linq에서 내부 조인 구문을 사용하지 않으므로 해당 구문은 동일하지 않습니다.

var reports = from rl in db.ReportLists 
       from ri in rl.ReportItems 
       from r in ri.Reports 
       where (
        from report in db.Reports 
        group report by report.seedLot into g 
        select g.Max(rep => rep.createdDate)).Contains(r.CreatedDate) 
       select rl; 

내가 포함하여 내가 그 그룹에 대한 구문 권리를 가지고 100 % 해요 (나는 매일 그룹화를 많이하지 않는다) : 당신이 봤어. LINQ 공급자가 Max (또는 Contains)를 지원하지 않으면 클라이언트 측에서 eveything을 가져오고 이는 많은 데이터를 통해 철수하게됩니다.

+0

죄송합니다.이 statenen은 내가 필요한 것을 정확하게 수행하지 않습니다. 그들은 중복없이 최상위 보고서를 반환하지만 (내 내부 linq 문은 이미이를 수행합니다.) 필요한 보고서는 reportItem에서 보고서의 목록이 아닌 각각의 제목으로 반환되는 것이지만 모두 포함 된 reportList입니다 reportItems는 해당 제목에 대한 모든 해당 보고서를 포함합니다. – DMCApps

+0

아. 당신이해야 할 일은 r 대신에 rl로 되돌아가는 것입니다. –

+0

아직도 꽤 :(이것은 각 보고서에 대해 6 개의 보고서 목록을 반환합니다. 내가 필요한 것은 3 개의 보고서가 있기 때문에 각각 3 개의 보고서를 포함하는 2 개의 reportItem을 포함하는 하나의 보고서 목록입니다. 각 제목) 그 값은 내가 현재 DB를 어떻게 설정했는지에 따라 달라지며 더 많은 데이터가 들어가고/변경 될 때마다 바뀔 것입니다. – DMCApps

0

귀하가 제공하는 세부 정보는 완전히 명확하지는 않지만 훨씬 명확하게 제공하므로 두 가지 대안을 제공 할 것입니다.(당신이 ReportItemsTitle에 의해 그룹에 보인다 때문에)

from rl in context.ReportLists 
from ri in rl.ReportItems 
from r in ri.Reports 
group r by r.Lot into g 
select g.OrderByDescending(x => x.createdDate).FirstOrDefault() 

나 : 지금은 매우 간결하고 포괄적 인 구문은 가능한 한 탐색의 호텔이 편리 후드

from rl in context.ReportLists 
from ri in rl.ReportItems 
group ri by ri.Title into g 
select g.Select(x => x.Reports 
         .OrderByDescending(x => x.createdDate).FirstOrDefault()) 

이 또한 SQL을 생산 조인 할 수 있지만 어색한 구문은 필요하지 않습니다. linq 유창한 구문에서 그것은 SelectMany() s로 귀결됩니다.

당신도 알다시피, 나는 여전히 LotTitle의 역할을 알아낼 수 없지만 대안이 자신의 사양에 맞는 물질을 줄 수 있기를 바랍니다.

+0

죄송합니다. 이러한 진술은 내가 필요한 것을 정확하게 수행하지 못합니다.그들은 중복없이 최상위 보고서를 반환하지만 (내 내부 linq 문은 이미이를 수행합니다.) 필요한 보고서는 reportItem에서 보고서의 목록이 아닌 각각의 제목으로 반환되는 것이지만 모두 포함 된 reportList입니다 그러면 reportItems에는 해당 제목에 대한 모든 관련 보고서 (최대 날짜 포함)가 포함됩니다. – DMCApps

+0

컬렉션을 부분적으로 채우려면 ['DataLoadOptions'] (http://msdn.microsoft.com/en-us/library/bb534361), esp. 'AssociateWith'. 또는 보고서를 통해 reportItem 및 reportList를 다시 가져올 수 있도록 양방향 탐색 속성을 만들어야합니다. –