从Linq2Sql </foreignkey>中的IQueryable <foreignkey>获取映射行

时间:2010-01-04 17:02:27

标签: linq linq-to-sql iqueryable

情况是:网页显示登录用户的聚会列表。在此Queryable组中,可能是用户订阅但尚未加载此页面之前尚未查看的Gatherings。既然此用户已经查看了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次访问数据库?

1 个答案:

答案 0 :(得分:0)

与此处相同的问题:linq question: querying nested collections

解决方案是改变这个:

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();