집계 SQL을 사용하여 LINQ 쿼리로 왼쪽 조인을 가장 우아하게 표현하는 방법

StackOverflow https://stackoverflow.com/questions/832

  •  08-06-2019
  •  | 
  •  

문제

SQL:

SELECT
   u.id,
   u.name,
   isnull(MAX(h.dateCol), '1900-01-01') dateColWithDefault
FROM universe u
LEFT JOIN history h 
   ON u.id=h.id 
   AND h.dateCol<GETDATE()-1
GROUP BY u.Id, u.name
도움이 되었습니까?

해결책

Null 값 처리를 코드로 연기하는 솔루션이기는 하지만 다음과 같을 수 있습니다.

어제 DateTime = DateTime.Now.Date.AddDays(-1);

var collection=
    from u in db.Universe
    select new
    {
        u.id,
        u.name,
        MaxDate =(DateTime?)
       (
           from h in db.History
           where u.Id == h.Id
           && h.dateCol < yesterday
           select h.dateCol 
       ).Max()
    };

이는 정확히 동일한 SQL을 생성하지는 않지만 동일한 논리적 결과를 제공합니다."복잡한" SQL 쿼리를 LINQ로 변환하는 것이 항상 간단한 것은 아닙니다.

다른 팁

var collection=
    from u in db.Universe
    select new
    {
        u.id,
        u.name,
        MaxDate =(DateTime?)
       (
           from h in db.History
           where u.Id == h.Id
           && h.dateCol < yesterday
           select h.dateCol 
       ).Max()
    };

위의 코드를 사용하면 정상적으로 작동할 것입니다!

이것이 완전한 답변은 아니지만 왼쪽 조인 부분에서 다음과 같이 DefaultIfEmpty 연산자를 사용할 수 있습니다.

var collection = 
from u in db.Universe
join history in db.History on u.id = history.id into temp
from h in temp.DefaultIfEmpty()
where h.dateCol < DateTime.Now.Date.AddDays(-1)
select u.id, u.name, h.dateCol ?? '1900-01-01'

아직 groupby 명령을 수행할 필요가 없었기 때문에 잘못된 경로로 보내지 않도록 생략했습니다.주목해야 할 다른 두 가지 사항.위와 같이 문제를 해결할 수 있는 방법이 있지만 실제로 두 매개변수를 결합할 수 없었습니다.또한, ??연산자는 SQL의 isnull 대신 정말 잘 작동합니다.

당신은 join into 그룹 쿼리를 생성하는 구성입니다.

TestContext db = new TestContext(CreateSparqlTripleStore());
var q = from a in db.Album
        join t in db.Track on a.Name equals t.AlbumName into tracks
        select new Album{Name = a.Name, Tracks = tracks};
foreach(var album in q){
    Console.WriteLine(album.Name);
    foreach (Track track in album.Tracks)
    {
        Console.WriteLine(track.Title);
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top