如果我有一个具有多个条件且一个用户选择多个条件的规则,如何编写一个linq查询,为我提供所有规则,其中该规则中的每个条件都存在于用户的选定条件下?
以下是我目前在SQL中的做法:
表格
rule:
ruleId int
categoryId int
ruleCriteria:
ruleId int,
criteriaId int
@userCriteria:
criteriaId int
categoryId int
查询
SELECT
r.ruleId
FROM dbo.rule r
INNER JOIN dbo.ruleCriteria rc ON r.ruleId= rc.ruleId
LEFT OUTER JOIN @userCriteria uc
ON rc.criteriaId = uc.criteriaId
AND r.categoryId = uc.categoryId
GROUP BY r.ruleId
HAVING COUNT(rc.criteriaId) = COUNT(uc.criteriaId)
对于linq查询,我将拥有这些对象(更多非规范化,但如果有帮助,我可以将它们放在与表相同的结构中):
userCriteria:
criteriaId int
categoryId int
ruleCriteria:
ruleId int
categoryId int
criteriaId int
我的目标与获取不同匹配规则列表的SQL查询相同。你会怎么做?
答案 0 :(得分:1)
我在LINQPad中玩了一些测试数据,这就是我想出来的。
from rc in ruleCriteria
group new { rc.criteriaId, rc.categoryId } by rc.ruleId into rules
where rules.Count() == userCriteria.Count(uc =>
rules.Contains(new { uc.criteriaId, uc.categoryId }))
select rules.Key
以下是逐行说明:
ruleCriteria
{ criteriaId, categoryId }
对ruleId
之类的条件进行分组,并将其保存在rules
userCriteria
的数量是否与规则总数相同,这意味着用户具有所有条件。ruleId
。答案 1 :(得分:1)
此查询生成的SQL比另一个更好,而且更直接:
from rc in ruleCriterias
group rc by rc.ruleId into rules
where rules.All(rc => userCriterias.Any(uc =>
uc.criteriaId == rc.criteriaId && uc.categoryId == rc.categoryId))
select rules.Key
您应确保所有列都是NOT NULL
,因为如果不是,则必须生成额外的SQL以检查事物是否为空。
答案 2 :(得分:0)
除非我误解(因此过于简单地解决问题),否则所有.All()方法都是你需要的。
var userCriteria = ; //TODO: Build user criteria
var result = context.Rules.Where(r => r.CategoryId == userCriteria.CategoryId
&& r.RuleCriteria.All(rc => rc.id == userCriteria.CriteriaId));
这将只返回所有包含标准符合您条件的rulls。我不能保证你的sql