寻找LINQ中的重叠利益

时间:2011-06-17 04:50:22

标签: c# entity-framework linq-to-entities

我有一个模型,其中一个地方有一些描述,这些描述与兴趣(place.description.interests)相关联。查看场所视图的用户在模型中表示为用户,他也有许多兴趣。

我想要做的是按重叠的兴趣(包括零重叠)对描述进行排序,我目前的Linq是:

place dest = (from p in _db.places
                          where p.short_name == id
                          select p).Single();

 return View(dest);

现在,以下内容将在SQL中针对相关架构执行我想要的操作:

SELECT COUNT(interest_user.user_id) AS matches, description.*
FROM description JOIN interest_description ON description.user_id = interest_description.user_id AND description.place_id = interest_description.place_id
    JOIN interest ON interest_description.interest_id = interest.interest_id
    LEFT JOIN interest_user ON interest.interest_id = interest_user.interest_id 
WHERE interest_user.user_id = 2
    AND description.place_id = 1
GROUP BY interest_description.user_id, interest_description.place_id
ORDER BY matches DESC

但我对Linq来说太新了,不知道如何正确处理这个问题。理想情况下,我可以在传递强类型模型时将其拉下来。

到目前为止我已经设法了:

var desc = from d in _db.descriptions
                       from i in d.interests
                       from u in i.users.DefaultIfEmpty()
                       where d.place_id == PlaceID
                           && (u.user_id == userID

(PlaceID和UserID是传递给管理它的控制器的参数)。

简单地说,鉴于这个linq,我只需要返回d,按照i的计数排序。

我的模特 enter image description here

2 个答案:

答案 0 :(得分:3)

place current_place =
    _db.places
    .Include("descriptions.interests.users")
    .Where(p => p.place_id == place_id)
    .First();

var interesting_descriptions =
    from description1 in current_place.descriptions
    select new {
        description = description1,
        matches = (
            from interest1 in description1.interests
            from user1 in interest1.users
            where user1.user_id = user_id
            select 1
        ).Count()
    } into result
    orderby result.matches descending
    select result;

这大致相当于SQL

SELECT
    description.*,
    (
        SELECT COUNT(*)
        FROM interest_description
        INNER JOIN interest_user
            ON interest_user.interest_id = interest_description.interest_id
        WHERE interest_description.place_id = description.place_id
        AND interest_description.user_id = description.user_id
        AND interest_user.user_id = @user_id
    ) AS matches
FROM description
WHERE place_id = @place_id
ORDER BY matches DESC

对于与给定地点相关联的每个描述,它会计算给定用户在任何相关兴趣上出现的次数。

对于与用户没有任何共同兴趣的描述,它会给matches = 0。

由于GROUP BY / group ... by ... into很难处理带条件的空集,因此必须使用内部查询。

答案 1 :(得分:3)

当您的linq查询变得过于复杂时,我建议您在数据库中创建视图并将它们放在dbml designer上。我在几种情况下经历过在linq查询中进行大量分组导致效率低下的sql。使用视图不仅会导致直接的linq查询,还会使用您想要的sql。