NHibernate按子集合项过滤器集合

时间:2014-05-18 03:43:14

标签: nhibernate queryover

健康记录可能有症状,其中包含一些单词。 (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();
    }
}

1 个答案:

答案 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语句)

相关问题