Linq to Sql:每组返回有限的行数

时间:2011-01-19 01:54:09

标签: c# linq-to-sql

想象一下,Products表有以下数据:


    ProductID    UserName   ProductName
    -----------------------------------
    1            User1      Product1
    2            User1      Product2
    3            User2      Product3
    4            User3      Product4
    5            User1      Product5
    6            User2      Product6
    7            User2      Product7
    8            User1      Product8

还有另一个名为UserLimit的表:


    UserName    DisplayLimit
    -------------------------
    User1       3
    User2       2
    User3       2

此表显示每位用户应返回的最大产品数量 我想要完成的是使用Linq to Sql查询返回:


    ProductID     UserName    ProductName
    --------------------------------------
    1             User1       Product1
    2             User1       Product2
    5             User1       Product5
    3             User2       Product3
    6             User2       Product6
    4             User3       Product4

为每个用户返回的产品数量仅限于UserLimit表中的DisplayLimit值。

3 个答案:

答案 0 :(得分:3)

在用户上使用分组,您可以轻松访问包含正确数量产品的每个组。

var limitedUsers = from p in dc.Products
                   group p by p.UserName into g
                   select new
                   {
                     UserName = g.Key,
                     Products = g.Take(dc.UserLimits
                                         .Where(u => u.UserName == g.Key)
                                         .Single().DisplayLimit)
                   };

答案 1 :(得分:2)

不确定如何将链接转换为s,但如果可能,您可以尝试使用DENSE_RANK函数。例如,下面的查询将返回每个用户的最后3个项目。这个限制对所有用户来说都很常见,但没有什么能真正阻止链接到有限制的表。

declare @numberOfProjects int
set @numberOfProjects = 3

;with topNProjects(userid, projectid, createdtutc, dense_rank)
as (
    select p.userid, P.ProjectId, p.CreatedDtUtc, DENSE_RANK() OVER (PARTITION BY P.UserId ORDER BY P.ProjectId) AS DENSE_RANK
    from DS_Project P
)
select userid, projectid, createdtutc from topNProjects
where dense_rank <= @numberOfProjects
order by projectid desc

EDITED:尝试了LINQed解决方案并提出了以下建议。我认为你所要做的就是用数据上下文中对表的引用替换我的集合。

        Dictionary<int, string> userProjects = new Dictionary<int, string>
        {
            { 1, "User1" },
            { 2, "User1" },
            { 3, "User2" },
            { 4, "User3" },
            { 5, "User1" },
            { 6, "User2" },
            { 7, "User2" },
            { 8, "User1" },
        };
        Dictionary<string, int> limits = new Dictionary<string, int>
        {
            { "User1", 3 },
            { "User2", 2 },
            { "User3", 2 },
        };


        var ranked = 
            from up in userProjects
            join l in limits on up.Value equals l.Key
            orderby up.Value
            where (from upr in userProjects
                   where upr.Value == up.Value && upr.Key <= up.Key
                   select upr).Count() <= l.Value
            select up;

结果如下所示:您正在寻找:

1, User1
2, User1
5, User1
3, User2
6, User2
4, User3

答案 2 :(得分:1)

如果查询需要是Linq,您可能需要这样的内容:

var q = tblProducts.where(p => false);
foreach (var item in tblDispLimit)
    q = q.Concat(tblProducts.where(p => p.UserName == item.UserName).Take(item.DisplayLimit));