想象一下,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值。
答案 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));