将 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
我有一个类似的查询,它工作正常。如果一个学生获得了不止一门课程,它会列出所有课程:
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