将 Sql 转换为 Linq(到实体)

Converting Sql to Linq (to Entities)

我有一个类似的查询,它工作正常。如果一个学生获得了不止一门课程,它会列出所有课程:

SELECT ks.KullaniciKodu as username, ks.Sifre as password, k.adi as firstname, k.soyadi as lastname, k.Email as email, 
    MAX(CASE WHEN c.DERSKODU = 'ENF100' THEN 'ENF100' ELSE '' END)As course1,
    MAX(CASE WHEN c.DERSKODU = 'ATA101' THEN 'ATA101' ELSE '' END) As course2,
    MAX(CASE WHEN c.DERSKODU = 'TDB101' THEN 'TDB101' ELSE '' END) As course3,
    MAX(CASE WHEN c.DERSKODU = 'İNG101' THEN 'İNG101' ELSE '' END) As course4
FROM Kayit k
JOIN DersNotu dn ON dn.KayitNo = k.KayitNo
JOIN Ders c ON c.DersKayitNo = dn.DersKayitNo AND c.DERSKODU IN ('ENF100','ATA101','TDB101', 'İNG101') AND c.DONEM = '201512'
JOIN KullaniciSifre ks ON ks.KullaniciKodu = k.KullaniciKodu
GROUP BY ks.KullaniciKodu, ks.Sifre, k.adi, k.soyadi, k.Email

但是当我将它转换为 Linq(实体)时,它只能获得一门课程或所有课程都为空。这段代码的区别和问题在哪里?

from k in db.Kayit
join dn in db.DersNotu on k.KayitNo equals dn.KayitNo
join c in db.Ders on dn.DersKayitNo equals c.DersKayitNo
join ks in db.KullaniciSifre on k.KullaniciKodu equals ks.KullaniciKodu
where
     (new string[] { "ENF100", "ATA101", "TDB101", "İNG101" }).Contains(c.DersKodu) &&
     c.Donem == 201512 
group new { ks, k, c } by new
{
     ks.KullaniciKodu,
     ks.Sifre,
     k.Adi,
     k.Soyadi,
     k.Email
     } into g
 select new 
 {
     KullaniciKodu = g.Key.KullaniciKodu,
     Sifre = g.Key.Sifre,
     Adi = g.Key.Adi,
     Soyadi = g.Key.Soyadi,
     Email = g.Max(p => (
         p.k.Email == string.Empty ? "NULL" : p.k.Email)),
     Course1 = g.Max(p => (
         p.c.DersKodu == "ENF100" ? "ENF100,1" : "NULL,1")),
     Course2 = g.Max(p => (
         p.c.DersKodu == "ATA101" ? "ATA101,1" : "NULL,1")),
     Course3 = g.Max(p => (
         p.c.DersKodu == "TDB101" ? "TDB101,1" : "NULL,1")),
     Course4 = g.Max(p => (
         p.c.DersKodu == "İNG101" ? "İNG101,1" : "NULL,1"))
 }

在SQL中使用MAX只是解决问题的一个技巧。您不应将其显式转换为 LINQToEntity。这里的问题是你对字符串使用 Max 。在您的情况下,NULL,1 似乎总是被选为最大值,但 TDB101,1.

除外

这里的实际逻辑是 ENF100,如果找到,则项目 "ENF100",否则项目 "NULL,1"。其他人也是同样的逻辑。所以应该是这样的:

 Course1 = g.Any(p => p.c.DersKodu == "ENF100") ? "ENF100,1" : "NULL,1",
 Course2 = g.Any(p => p.c.DersKodu == "ATA101") ? "ATA101,1" : "NULL,1",
 Course3 = g.Any(p => p.c.DersKodu == "TDB101") ? "TDB101,1" : "NULL,1",
 Course4 = g.Any(p => p.c.DersKodu == "İNG101") ? "İNG101,1" : "NULL,1"

另外Email投射错误,已经包含在群秘钥中,所以直接投射群秘钥即可:

 Email = g.Key.Email