2013-10-17 46 views
0

尝试将以下SQL查询转换为LINQ,但我坚持由ClientCompany进行分组。LINQ中的分组和MIN()

SELECT TOP 300 ClientCompany, 
CASE WHEN MIN(FeatureID) = 12 THEN 1 ELSE 0 END as Sort 
FROM Ad 
LEFT JOIN AdFeature 
ON Ad.ID = AdFeature.AdID 
WHERE (AdFeature.FeatureID = 13 OR AdFeature.FeatureID = 12) 
AND SiteID = 2 
GROUP BY ClientCompany 
ORDER BY Sort DESC 

我尝试将其转换为LINQ:

(from a in Ads 
join af in AdFeatures 
on new { 
join1 = a.ID, 
join3 = 2 
} equals new { 
join1 = af.AdID, 
join3 = af.SiteID 
} 
let sort = (
af.FeatureID == 12 ? 1 : 0 
) 
orderby sort descending 
where af.FeatureID == 13 || af.FeatureID == 12 
select new { a.ClientCompany, sort }).Take(300) 

我将如何使用MIN(FeatureID)GROUP BY ClientCompany在LINQ,所以我只有每ClientCompany得到单列回来?

编辑

这个工作!根据Daniel Hilgarth的回答。这个解决方案有什么可怕的错误吗?

Ads.Join(AdFeatures, x => x.ID, x => x.AdID, 
(a, af) => new { Ad = a, AdFeature = af }) 
.Where(x => x.AdFeature.FeatureID == 12 || x.AdFeature.FeatureID == 13) 
.Where(x => x.AdFeature.SiteID == 2) 
.GroupBy(x => x.Ad.ClientCompany) 
.Select(g => new { ClientCompany = g.Key, Sort = g.Min(x => x.AdFeature.FeatureID) == 12 ? 1 : 0 }) 
.OrderByDescending(x => x.Sort) 
.Take(300) 

回答

4

试试这个:

Ads.Join(AdFeatures, x => x.FeatureID, x => x.FeatureID, 
     (a, af) => new { Ad = a, AdFeature = af }) 
    .Where(x => x.AdFeature.FeatureID == 12 || x.AdFeature.FeatureID == 13) 
    .Where(x => x.AdFeature.SiteID == 2) 
    .GroupBy(x => x.Ad.ClientCompany) 
    .Select(g => new { ClientCompany = g.Key, 
         Sort = g.Min(x => x.AdFeature.FeatureID) == 12 ? 1 : 0 }); 

请注意,我改变了左外连接到内部联接,因为你原来的查询访问AdFeature无条件,使其成为一个内部联接。

+0

所有答案都包含我不习惯的lambda表达式。你能解释一下这里发生了什么吗? 当我用LINQPad 4试用时,它不工作。 _'LINQPad.User.Ad'不包含'Fea​​tureID'的定义,也没有接受'LINQPad'类型的第一个参数的扩展方法'FeatureID' .User.Ad'可以找到(按F4添加使用指令或程序集引用)_ –

+1

使用了一些修改(在原始文章中更新)。谢谢! –

0

试试这个:

(from a in ads 
join af in AdFeatures on a.ID equals af.AdID into g 
from x in g.DefaultIfEmpty() 
where x.FeatureID == 13 || x.FeatureID == 12 
where x.SiteID == 2 
orderby a.Sort descending 
group a by a.ClientCompany into g2 
from x2 in g2 
let sort = g2.Select(T => T.FeatureID).Min() == 12 ? 1 : 0 
select new { a.ClientCompany, Sort = sort }).Take(300); 

为什么需要分组呢?

+0

分组是为了获得每个公司的最小值。你的查询得到全局的最小值,所以它甚至可能为0. –

0

您好我会写这样的

  context.Ads.Where(ad => ad.AdFeatures.Any(feature => (feature.FeatureID == 13 || feature.FeatureID == 12) && feature.SiteID == 2)) 
        .GroupBy(ad => ad.ClientCompany) 
        .Select(ads => new 
        { 
         cc = ads.Key, sort = ads.SelectMany(ad => ad.AdFeatures) 
               .Select(feature => feature.FeatureID) 
               .Min() == 12 
        }) 
        .OrderBy(arg => arg.sort).Take(300);