2011-06-17 81 views
6

我有一个模型,其中一个地方有一些描述,这些描述与兴趣(place.description.interests)相关联。用户查看地点的视图在模型中以用户身份表示,他们也有许多兴趣。LINQ中找到重叠兴趣

我想要做的排序是重叠的利益(包括零重叠),那里有我当前的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和用户名是传递给管理该控制器参数)。

简而言之,考虑到这个linq,我只需要返回d,按i计数。

我的模型 enter image description here

+0

你能举出输入数据的例子吗?应该给他们什么结果? – 2011-06-17 06:21:23

+0

好吧,我有一个ID为1的地方,ID为1的用户。我的用户有兴趣1,2,4。这个地方有1,2,3个描述,其中描述1有兴趣1,2,描述2有兴趣2,3,描述3有兴趣1,2,3,4。当用户1查看地点1时,说明应按3,1,2排序,因为3有三个重叠的兴趣,1有两个重叠的兴趣,2有一个重叠的兴趣。 – 2011-06-17 16:03:08

回答

3

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

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很难处理带条件的空集,所以需要使用内部查询。

+0

我已更新我的示例SQL以准确显示我正在尝试执行的操作,恐怕我无法将您的示例翻译成该示例。请注意,最后,我想要一个描述列表,根据它们与用户有多少重叠的兴趣来排序,对匹配本身不感兴趣,以便我可以将结果传递给强类型化为描述的视图实体。 – 2011-06-20 03:36:28

+0

大家好,最后不仅仅是使用视图,而是使用我上面发布的查询并返回描述的存储过程更有效。*,允许我通过函数导入将SP映射到描述实体,并得到我所需要的。非常感谢帮助! – 2011-06-21 03:42:46