代码之家  ›  专栏  ›  技术社区  ›  Dai Bok

跨多个表的NHibernate查询

  •  8
  • Dai Bok  · 技术社区  · 14 年前

    我正在使用NHibernate,并试图找出如何编写一个查询,搜索我所有实体的名称, 并列出结果。作为一个简单的例子,我有以下对象;

    public class Cat {
    public string name {get; set;}
    }
    
    public class Dog {
        public string name {get; set;}
    }
    
    public class Owner {
        public string firstname {get; set;}
        public string lastname {get; set;}
    }
    

    最后我想创建一个查询,例如,它返回所有宠物主人的名字包含“ted”,或者宠物的名字包含“ted”。

    SELECT TOP 10 d.*, c.*, o.* FROM owners AS o
    INNER JOIN dogs AS d ON o.id = d.ownerId 
    INNER JOIN cats AS c ON o.id = c.ownerId
    WHERE o.lastname like '%ted%' 
    OR o.firstname like '%ted%' 
    OR c.name like '%ted%' 
    OR d.name like '%ted%' 
    

    当我用这样的标准来做的时候:

        var criteria = session.CreateCriteria<Owner>()
            .Add(
            Restrictions.Disjunction()
                .Add(Restrictions.Like("FirstName", keyword, MatchMode.Anywhere))
                .Add(Restrictions.Like("LastName", keyword, MatchMode.Anywhere))
            )
            .CreateCriteria("Dog").Add(Restrictions.Like("Name", keyword, MatchMode.Anywhere))
            .CreateCriteria("Cat").Add(Restrictions.Like("Name", keyword, MatchMode.Anywhere));
            return criteria.List<Owner>();
    

       SELECT TOP 10 d.*, c.*, o.* FROM owners AS o
       INNER JOIN dogs AS d ON o.id = d.ownerId 
       INNER JOIN cats AS c ON o.id = c.ownerId 
       WHERE o.lastname like '%ted%' 
       OR o.firstname like '%ted%' 
       AND d.name like '%ted%'
       AND c.name like '%ted%'
    

    如何调整查询,使.CreateCriteria(“Dog”)和.CreateCriteria(“Cat”)生成OR而不是and?

    谢谢你的帮助。

    2 回复  |  直到 14 年前
        1
  •  5
  •   YYFish    14 年前

    试试这个,可能有用。

    var criteria = session.CreateCriteria<Owner>()
                .CreateAlias("Dog", "d")
                .CreateAlias("Cat", "c")
                .Add(
                Restrictions.Disjunction()
                    .Add(Restrictions.Like("FirstName", keyword, MatchMode.Anywhere))
                    .Add(Restrictions.Like("LastName", keyword, MatchMode.Anywhere))
                    .Add(Restrictions.Like("c.Name", keyword, MatchMode.Anywhere))
                    .Add(Restrictions.Like("d.Name", keyword, MatchMode.Anywhere))
                );
    
        2
  •  2
  •   AlexCuse    14 年前

    您需要使用Expression.Or(criteria1,criteria2)组合这两个条件

    更多信息: http://devlicio.us/blogs/derik_whittaker/archive/2009/04/21/creating-a-nested-or-statement-with-nhibernate-using-the-criteria-convention.aspx

    嗯,我想应该是这样的(借用了BuggyDigger的代码)

    var criteria = session.CreateCriteria<Owner>()
        .CreateAlias("Dog", "d")
        .CreateAlias("Cat", "c")
        .Add(Expression.Or(Expression.Like("c.Name", keyword, MatchMode.Anywhere)
                , Expression.Like("d.Name", keyword, MatchMode.Anywhere))
            );
    

    但我没注意到你想要什么。在这种情况下,如BuggyDigger所示,将这些标准添加到析取中可能是一种可行的方法。