我有一个模型,其中一个地方有一些描述,这些描述与兴趣(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的计数排序。
我的模特
答案 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。