按子集合项列出的NHibernate筛选器集合

按子集合项列出的NHibernate筛选器集合,nhibernate,queryover,Nhibernate,Queryover,健康记录可能有症状,包括一些单词 我需要的是:通过给定的一组单词返回带有相应症状的健康记录 我有以下代码: public IEnumerable<HealthRecord> GetByWords(IEnumerable<Word> words) { var wordsIds = words.Select(w => w.Id).ToList(); Word word = null; HealthRecord hr = null; ISe

健康记录可能有症状,包括一些单词

我需要的是:通过给定的一组单词返回带有相应症状的健康记录

我有以下代码:

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();
    }
}

这里我们应该使用的是:内部选择,即子查询。即使使用多对多映射,我们也可以这样做,但性能会受到影响

更简单,我更喜欢的方法是不使用多对多映射。因为使用显式映射的配对对象,查询将更容易

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;
这应该行得通,这里也检查一些类似的问题:

一些提示说明了如何重新映射多对多,因为使用映射为对象的配对表,我们可以构造类似的简化构造,从而生成更好的SQL语句


在单词只包含一项之前,一切正常。否则,生成的SQL出现语法错误:[从健康记录中选择此Id作为Id10\u 0,从健康记录中选择此症状Id作为症状Id10\u 0。在中选择此Id作为y0。从症状中选择此Id作为y0。从症状中选择此内部连接症状文字3。在该上,Id=文字3。症状Id内部连接文字1。在文字3上。文字Id=文字1。Id,其中文字1。Id作为jetJoinAlias0,]我明白了。但你知道吗?这将是…一行多中的第一个问题,我会说。多对多只会带来问题。但是你的配对表包含自己的ID列。这很简单,因为它可以映射为标准实体。在这样的关系上搜索子查询会容易得多。以后…你还可以为了更好地扩展该对象,IsActive……将对其进行查看……但是……不确定是否能提供更多帮助。我只是重新测试了,没有重现您的问题。在我的测试示例中,我按原样使用了查询,它可以处理任意数量的单词。事实上,您在注释中显示的SQL代码片段非常奇怪,例如,来自症状的大括号是0。我按照您的建议添加了SymptomWords实体。最后一个查询是session.QueryOver=>hr.JoinAlias=>hr.Symptom,=>Symptom.JoinAlias=>Symptom.SymptomWords,=>sw.JoinAlias=>sw.Word,=>WhereRestrictionOn=>Word.Id.IsInwordsIds.TransformUsingTransformers.distincTrotenty.list很高兴看到这一点!干得不错。享受NHibernate;