我想运行一个linq查询,它会将值返回到我的自定义DTO。这个特定的linq查询需要考虑来自多个表的连接,使用switch case语句,count(*)和group by
这是查询的SQL版本示例,我将需要LinQ等效于...
select
slm.SLType,
count(c.EStatID) as EStat,
COUNT(cpd.TrId) as Training,
COUNT(
CASE WHEN cpd.TrStat= 44 THEN 1
WHEN cpd.TrStat!= 44 THEN NULL
WHEN cpd.TrStat IS NULL THEN NULL
END) as TrainingComplete,
COUNT(
CASE WHEN cpd.CndAssess = 44 THEN 1
WHEN cpd.CndAssess != 44 THEN NULL
WHEN cpd.CndAssess IS NULL THEN NULL
END) as AssessmentComplete
from TabC c , TabCPD cpd, TabSLM slm
where cpd.SLid = slm.SLid
and c.Id= cpd.CID
and c.O_Id = 1
group by slm.SLType
它以下列格式返回记录。我已将每条记录作为一个新行,其中的字段以逗号分隔。以下数字仅作为示例
TypeA, 0 , 1 , 1, 0
TypeB, 1 , 0 , 1, 0
我正在尝试以下面的格式创建一个linq查询而没有太多运气
var query =
from c in TabC, ......
select new MyCustomTableC_DTO
{
DTOproperty = c.MatchingTable property,....
}
MyCustomTableC_DTO将为查询中的每个字段提供一个属性。知道怎么做到这一点?我将用于构建MyCustomTableC_DTO类型列表的查询
感谢您的时间......
答案 0 :(得分:7)
当您尝试逐行将该SQL语句转换为LINQ时,您将得到如下内容:
from row in (
from c in db.TabC
from cpd in db.TabPD
from slm in db.TabSLM
where cpd.SLid == slm.SLid
where c.Id == cpd.CID
where c.O_Id == 1
select new { c, cpd, slm })
group row in row.slm.SLType into g
select new
{
SLType = g.Key,
EStat = g.Count(r => r.c.EstatID != null),
Training = g.Count(r => r.cpd.TrId != null),
TrainingComplete =
g.Count(r => r.cpd.TrStat == 44),
AssessmentComplete =
g.Count(r => r.cpd.CndAssess == 44)
};
然而,这个查询使事情复杂化并完全忽略了这样一个事实:Entity Framework更多地了解模型并将所有外键生成为实体上的属性。除此之外,使用LINQ,您必须经常以相反的方式处理问题。例如,在您的情况下,不要从TabC
或TabSLM
实体开始,而是从TabPD
开始,因为该表是交叉表。有了这些知识,我们可以像这样编写LINQ查询:
from cpd in db.TabCPDs
where cpd.TabC.O_Id == 1
group cpd by cpd.TabSLM.SLType into g
select new
{
SLType = g.Key,
EStat = g.Count(r => r.TabC.EstatID != null),
Training = g.Count(r => r.TrId != null),
TrainingComplete =
g.Count(r => r.TrStat == 44),
AssessmentComplete =
g.Count(r => r.CndAssess == 44)
};
这更简单,并且(如果我没有误会)具有相同的结果。