0

情况是:网页向登录用户显示聚会列表。在这个 Queryable 组中可能有用户订阅但在加载此页面之前尚未查看的 Gatherings。既然该用户已经查看了聚会,我想将它们标记为这样。

我可以通过使用 ToList() 和 Contains()(见下文)使其工作,但这意味着我必须对数据库进行 2 次访问:1 次用于 ToList(),1 次用于 foreach()。我尝试了其他方法来获取这些订阅,但它们最终变成了 EntitySet。

Users     Gatherings
=====     ==========
UserId    GatheringId

GatheringSubscriptions
======================
GatheringSubscriptionId
GatheringId
UserId
IsViewed

// update unviewed=>viewed for this user's subscription to each
// of these gatherings
public void MarkViewed(IQueryable<Gathering> gatherings, int userId) {
    List<int> gIdsList = gatherings.Select(g => g.GatheringId).ToList();
    IQueryable<GatheringSubscription> gSubs = db.GatheringSubscriptions
        .Where(gs =>
            gs.UserId == userId &&
            !gs.IsViewed &&
            gIdsList.Contains(gs.GatheringId))
        .Distinct();
    foreach (GatheringSubscription gSub in gSubs)
        gSub.IsViewed = true;
    db.SubmitChanges();
}

我怎样才能实现同样的目标,但只需要访问数据库 1 次?

4

1 回答 1

0

与此处相同的问题:linq 问题:查询嵌套集合

解决方案是改变这一点:

db.GatheringSubscriptions
    .Where(gs =>
        gs.UserId == userId &&
        !gs.IsViewed &&
        gIdsList.Contains(gs.GatheringId))
    .Distinct();

对此:

tickers.SelectMany(t => t.GatheringSubscriptions)
    .Where(gs =>
        gs.UserId == userId &&
        !gs.IsViewed)
    .Distinct();
于 2010-01-04T18:18:42.723 回答