[英]c# linq join with projection
因此,在我的商店应用中,我允许用户收藏自己喜欢的物品。 我想做的是在用户个人资料页面上显示收藏夹项目的列表,其中列表在相似的日期以降序排序。
我们有2个表需要联接,一个表是项目,另一个是收藏夹。
一个人如何将这两个表联接在一起,因此结果将满足以下条件:
结果将是此特定用户喜欢的项目列表。
结果将带有每个项目的注释列表(每个项目都有一个注释列表)。
结果将正确排序。
到目前为止,我想到了这个:
Items =
await _context.Favorites
.Join(
_context.Items,
f => f.ItemId,
i => i.Id,
(f, i) => new { f, i })
.Distinct()
.OrderByDescending(x => x.f.FavDate)
.Select(x => x.i)
.Skip(skip).Take(take)
.Include(c => c.ListOfComments)
.ToListAsync();
这是可行的,但不能满足第一个条件,即仅返回特定用户喜欢的项目,这将返回用户而非特定用户喜欢的项目的列表。
我试图在连接(_context.Favorites.Where(f.UserVoterId.equals(profileId)))之前添加where子句,但是它引发了异常。
解决此问题的一种方法是:
要选择特定用户的收藏夹项目( profileId
),您需要以下查询:
var favorites = _context.Favorites.OrderByDescending(f => f.FavDate)
.Join(_context.Items,
fav => new { fav.ItemId, UserId = fav.UserVoterId },
item => new { ItemId = item.Id, UserId = profileId },
(fav, item) => item)
.Skip(pageIndex * pageSize)
.Take(pageSize)
.ToList();
要加载评论,只需尝试以下一项(无论哪种有效):
var itemIds = favorites.Select(f => f.Id);
var comments = _context.Comments.Where(c => itemIds.Contains(c.ItemId))
.GroupBy(c => c.ItemId)
.ToDictionary(g => g.Key, g => g.ToArray());
要么
var items = _context.Comments
.GroupJoin(favorites,
comment => comment.ItemId,
favorite => favorite.Id,
(fav, comments) => new
{
Item = fav,
Comments = comment.ToArray()
});
在第一种情况下,该意见被添加到Dictionary<TItemId, Comment>
其中TItemId
是类型item.Id
,并获得对您想要使用某个项目的意见
var itemComments = comments[item.Id];
这是O(1)
运算。
在第二种情况下, items
集合将拥有您需要的所有数据,因此您必须将其投影到适合您需求的结构中。
注意:我之前提到的任何一种方法都是可行的,因为我不确定完全将GroupJoin
正确地转换为SQL,也不确定是否错过了对GroupJoin
方法的某些要求。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.