2012-02-19 155 views
0

我想运行一个linq查询,该查询将返回值到我的自定义DTO。这个特定的linq查询将需要考虑来自多个表的联接,使用switch case语句,count(*)和Linq查询与表连接,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查询

MyCustomTableC_DTO将在每个字段属性查询。任何想法如何做到这一点?查询我将用它来建立类型的列表MyCustomTableC_DTO

感谢您的时间...

+2

您可以将表前缀('c.','cpd.','slm.')添加到您的查询中,以便我们知道哪个列属于哪个表? – Diego 2012-02-19 19:24:24

+0

完成。编辑的问题。 – user20358 2012-02-19 19:55:42

回答

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,你必须经常以相反的方式来处理事情。例如,在你的情况下,不要从TabCTabSLM实体开始,而是从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)   
}; 

这是更简单,(如果我没有弄错)具有相同的效果。

+0

我需要在db.TabSLM中将slm连接到slm。你将如何修改这个查询呢? – user20358 2012-03-26 15:28:00

+0

标记我为答案,并在SO上发布一个新问题。 – Steven 2012-03-26 17:17:22