使用group by和多个order by将SQL转换为LINQ,嵌套select,top,“distinct”

时间:2011-03-02 10:15:16

标签: tsql linq-to-sql

我有以下SQL查询,我很难转换为LINQ。

目的:从表格中获取前10张优惠券,按其到期日期排序(即列出即将到期的那些),然后随机选择其中一张进行发布。

注意:由于数据库的结构方式,Codes表中可能存在重复的Coupon。因此,我使用GROUP BY来强制区分,因为我不能在子选择查询中使用DISTINCT(我认为这是正确的)。 SQL查询有效。

SELECT TOP 1
    c1.*
FROM
    Coupon c1
WHERE
    Code IN (
        SELECT TOP 10
            c2.Code
        FROM
            Coupon c2
        WHERE
            c2.Published = 0
        GROUP BY
            c2.Code,
            c2.Expires
        ORDER BY
            c2.Expires
    )
ORDER BY NEWID()

更新: 这与我的情况一样接近,但有两个问题:

var result1 = (from c in Coupons
        where c.Published == false
        orderby c.Expires
        group c by new { c.Code, c.Expires } into coupon
        select coupon.FirstOrDefault()).Take(10);

var result2 = (from c in result1
        orderby Guid.NewGuid()
        select c).Take(1);

2 个答案:

答案 0 :(得分:0)

这是一种可能的方式:

from c in Coupons
from cs in 
    ((from c in coupons
        where c.published == false
        select c).Distinct()
        ).Take(10)
where cs.ID == c.ID
select c

请记住,LINQ会创建一个强类型数据集,因此IN语句没有通用的等价物。我理解为了保持SQL紧,但LINQ可能不是最好的答案。如果您使用的是MS SQL Server(而非SQL Server Compact),则可能需要考虑将其作为存储过程。

答案 1 :(得分:0)

使用MercurioJ稍微有点错误的回复,结合另一个SO suggested random row solution我的解决方案是:

var result3 = (from c in _dataContext.Coupons
                from cs in
                    ((from c1 in _dataContext.Coupons
                        where
                        c1.IsPublished == false
                        select c1).Distinct()
                        ).Take(10)
                where cs.CouponId == c.CouponId
                orderby _dataContext.NewId()
                select c).Take(1);