【问题标题】:NHibernate Criteria questionNHibernate 标准问题
【发布时间】:2010-05-16 19:51:31
【问题描述】:

我有一个 person 对象,它可以有无限个名字。所以名字是另一个对象。

人---姓名
--- 名称
--- 名称

我想做的是编写一个 nhiberate 查询,使用它可以让我得到一个有特定名字的人。

所以一个查询可能是查找姓名为 alison 和 jane 和 philippa 的人,然后下一个查询可能是查找姓名为 alison 和 jane 的人。

我只想返回具有我正在搜索的所有名称的人。到目前为止,我已经得到了

ICriteria criteria = session.CreateCriteria(typeof (Person));
criteria.CreateAlias("Names", "name");
ICriterion expression = null;
foreach (string name in namesToFind)
{
    if (expression == null)
    {
        expression = Expression.Like("name.Value", "%" + name + "%");
    }
    else
    {
        expression = Expression.Or(
            expression,
            Expression.Like("name.Value", "%" + name + "%"));
    }
}

if (expression != null)
    criteria.Add(expression);

但这会返回每个人的任何名字,而不是所有名字。

谁能帮我解决这个问题?谢谢!

【问题讨论】:

    标签: nhibernate icriteria


    【解决方案1】:

    那不应该是 AND 表达式吗?

    像这样:

        ICriteria criteria = session.CreateCriteria(typeof (Person));
        criteria.CreateAlias("Names", "name");
        foreach (string name in namesToFind)
        {
            criteria.Add(Expression.Like("name.Value", "%" + name + "%"));
        }
    

    编辑

    好的。为了匹配您上面给出的查询,稍作更改以避免加入:

        ICriteria criteria = s.CreateCriteria(typeof(Person));
        foreach (string name in namesToFind)
        {
            criteria.Add(Subqueries.PropertyIn("Id",
                DetachedCriteria.For<Name>()
                    .Add(Restrictions.Like("Value", name, MatchMode.Anywhere))
                    .SetProjection(Projections.Property("Person"))));
        }
    

    这要求您在 Name 类上有一个名为 Person 的映射属性。

    【讨论】:

    • 那么你会得到像'%jane%'这样的名字和像'%philippa%'这样的名字的sql,这真的没有意义吗?
    • 唯一的名字必须是“philippa jane”或“jane philippa”才能工作 - 不是一个名字“jane”和一个名字“philippa”....跨度>
    • 好的。我必须学会更仔细地阅读。我已经更新了答案以反映您上面的 sql。
    【解决方案2】:

    有多种方法可以做到这一点。您可以为每个名称使用存在子查询。或者,您可以加入姓名,为每个姓名添加name like '%blah%',按人分组并添加having count(*) = nameCnt。但是,ICriteria 不支持 Have 子句,因此您需要使用 HQL。

    【讨论】:

      【解决方案3】:

      这是我想要得到的那种 sql:

      select * from person where Id in
      (
      select person.id from person inner join [name]
      on person.id = name.personId
       where name.value like '%jane%'
      )
      and id in
      (
      select person.id from person inner join [name]
      on person.id = name.personId
       where name.value like '%janice%'
      ) 
      and id in
      (
      select person.id from person inner join [name]
      on person.id = name.personId
       where name.value like '%louise%'
      ) 
      

      【讨论】:

      • 你应该编辑问题而不是添加这个作为答案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-25
      • 1970-01-01
      • 2013-12-22
      • 1970-01-01
      • 1970-01-01
      • 2012-11-21
      相关资源
      最近更新 更多