健康记录可能有症状,其中包含一些单词。 (ER diagram。)
我需要什么:通过给定的单词集返回具有相应症状的健康记录。
我有这段代码:
public IEnumerable<HealthRecord> GetByWords(IEnumerable<Word> words)
{
var wordsIds = words.Select(w => w.Id).ToList();
Word word = null;
HealthRecord hr = null;
ISession session = NHibernateHelper.GetSession();
{
return session.QueryOver<HealthRecord>(() => hr)
.WhereRestrictionOn(() => hr.Symptom).IsNotNull()
.Inner.JoinAlias(() => hr.Symptom.Words, () => word)
.WhereRestrictionOn(() => word.Id).IsIn(wordsIds)
.List();
}
}
答案 0 :(得分:0)
我们在这里应该使用的是:INNER SELECT,即subquery
。即使使用many-to-many
maping,我们也可以做到这一点,但性能会受到影响。
(更简单,我更喜欢)方式是不使用many-to-many
映射。因为使用显式映射的配对对象SymptomWord
,查询会更容易。
Word word = null;
Symptom symptom = null;
// the sub SELECT returning column Symptom.Id
var subq = QueryOver.Of<Symptom>(() => symptom)
// just symptoms refering the searched words
.Inner.JoinAlias(() => symptom.Words, () => word)
.WhereRestrictionOn(() => word.Id).IsIn(wordsIds)
// the result of inner select is
.Select(s => symptom.Id);
在下一步中,我们可以使用它进行过滤:
var list = session
// just query over HealthRecord here
.QueryOver<HealthRecord>()
.WithSubquery
// the ID of referenced Symptom is in that table
.WhereProperty(hr => hr.Symptom.Id)
// and will be filtered with our subquery
.In(subq)
.List<HelthRecord>();
return list;
这应该有用,也可以在这里检查一些类似的问题:
有些提示如何重新映射many-to-many
(因为将配对表映射为对象,我们可以构造类似且简化的构造,从而产生更好的SQL语句)