我有一个用户表和一个一对多的用户技能表。我需要能够根据技能搜索用户。此查询获取所需技能的列表并搜索具有这些技能的用户。我想根据用户拥有的所需技能的数量对用户进行排序。因此,如果用户仅拥有 3 种所需技能中的 1 种,那么他将比拥有 3 种所需技能中的 3 种的用户在列表中的位置更靠后。
我从正在搜索的技能 ID 的逗号分隔列表开始:
List<short> searchedSkillsRaw = skills.Value.Split(',').Select(i => short.Parse(i)).ToList();
然后,我仅过滤掉可搜索的用户类型:
List<User> users = (from u in db.Users
where
u.Verified == true &&
u.Level > 0 &&
u.Type == 1 &&
(u.UserDetail.City == city.SelectedValue || u.UserDetail.City == null)
select u).ToList();
然后是疯狂的部分:
var fUsers = from u in users
select new
{
u.Id,
u.FirstName,
u.LastName,
u.UserName,
UserPhone = u.UserDetail.Phone,
UserSkills = (from uskills in u.UserSkills
join skillsJoin in configSkills on uskills.SkillId equals skillsJoin.ValueIdInt into tempSkills
from skillsJoin in tempSkills.DefaultIfEmpty()
where uskills.UserId == u.Id
select new
{
SkillId = uskills.SkillId,
SkillName = skillsJoin.Name,
SkillNameFound = searchedSkillsRaw.Contains(uskills.SkillId)
}),
UserSkillsFound = (from uskills in u.UserSkills
where uskills.UserId == u.Id && searchedSkillsRaw.Contains(uskills.SkillId)
select uskills.UserId).Count()
} into userResults
where userResults.UserSkillsFound > 0
orderby userResults.UserSkillsFound descending
select userResults;
这有效!但对我来说,它似乎 super 臃肿且效率低下。尤其是计算找到的技能数量的次要部分。
感谢您提供的任何建议。
--r
最佳答案
我认为这应该可以解决问题:
(from u in users
where u.UserSkills.Any(skill => searchedSkillsRaw.Contains(skill.SkillId))
select new
{
u.Id,
u.FirstName,
u.LastName,
u.UserName,
UserPhone = u.UserDetail.Phone,
UserSkills = u.UserSkills,
UserSkillsFound = u.UserSkills.Where(skill => searchedSkillsRaw.Contains(skill.SkillId)).Count()
} into userResults
orderby userResults.UserSkillsFound descending
select userResult).ToList();
但是,由于这是在 SQL Server 上执行的查询,我强烈建议从第一个查询中删除“ToList()”调用。因为这实际上会导致 LINQ 在 SQL 服务器上运行两个单独的查询。您应该将其更改为 IQueryable。 LINQ 的强大之处在于可以通过几个步骤构建查询,而无需在中间实际执行它。因此,仅应在构建整个查询的最后调用“ToList”。事实上,您当前所做的是在内存中而不是在数据库服务器上运行第二个查询。
对于您的 UserSkills 一对多关系,您不需要在 LINQ 中进行显式联接。您可以只访问集合属性。
如果您需要更多解释,请告诉我。
迈克尔
关于c# - 有没有更好的方法来编写这个 Frankenstein LINQ 查询,在子表中搜索值并按相关性对它们进行排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2428121/