【问题标题】:NHibernate - Query multiple tables with one queryNHibernate - 用一个查询查询多个表
【发布时间】:2011-08-14 18:34:27
【问题描述】:

我正在使用 NHibernate 2,我希望能够执行以下操作:

我有许多 DAO 类型。它们都是BaseDAO 的子类,但它们在NHibernate 映射中根本不相关。 (这些子类并不都有共同的属性。)

我想编写一个方法来搜索我所有的 DAO 类型并返回一个包含所有匹配项的 List<BaseDAO>

方法签名应该类似于:

public IList<BaseDAO> GlobalSearch(string searchTerm, int startIdx, int maxRows);

查询需要检查searchTerm 与域类型的所有string 属性。我们目前一次只针对一种类型执行此操作,使用的是一种构建Disjunction 的方法来搜索给定类型的所有属性。

private Disjunction BuildDisjunction(string searchTerm, Type type)

我想组合我所有域类型的所有析取并创建一个查询,该查询将返回BaseDAO 的列表。

这是我目前所拥有的:

public IList<DomainBase> GlobalSearch(string searchTerm, 
                                      int startIndex, int maxRows)
{
    ICriteria crit = GetCriteria<BaseDAO>();
    foreach (Type t in GetAllDomainTypes())
    {
        Disjunction disj = BuildDisjunction(searchTerm, t);
        // somehow use this disjunction
    }
    crit
        .AddOrder(Order.Asc("DispName"))
        .SetFirstResult(startIdx)
        .SetMaxResults(maxRows);
    return crit.List<BaseDAO>(); ;
}

这可能吗?如何修改/完成上述方法以实现我需要的功能?

【问题讨论】:

  • 我认为这不可能。想想你将如何在 SQL 中做到这一点,如果不可能在一个 SQL 查询中做到,那么在 NHibernate 中也将不可能做到。
  • @Vadim,这有点让我害怕。不幸的是,我对 SQL 的了解太少,不知道这是否可能。
  • 您在搜索基类的属性吗?如果是这样,则可以将每个查询生成到 MultiCritera 中,执行它并将所有结果填充回列表中。
  • @Phill,你能告诉我怎么做吗?但不是。我正在搜索所有子类的所有公共字符串属性。
  • 可能需要进行一些反思才能做到这一点,我几个小时后下班回家,我会看看我是否可以写一个例子,看看它是否是事实可能,我有 98% 的把握。会让你知道的。

标签: c# nhibernate criteria


【解决方案1】:

此方法仅适用于 MSSQL Server。

好的,我已经写了以下内容,我希望这是你所追求的,它可以被重构,但它会让你开始。

给定以下测试类:

public class BaseClass
{
    public virtual int Id { get; set; }   
}

public class TestClassOne : BaseClass
{
    public virtual string Name { get; set; }
}

public class TestClassTwo : BaseClass
{
    public virtual string Value { get; set; }
    public virtual string Hobby { get; set; }
}

public class TestClassThree : BaseClass
{
    public virtual string Month { get; set; }
    public virtual int Day { get; set; }
}

public class TestClassFour : BaseClass
{
    public virtual string Title { get; set; }
    public virtual string Content { get; set; }
}

可以通过反射来查询所有这些类,然后反射属于字符串类型的属性。

        var session = new SessionFactoryManager().CreateSessionFactory().OpenSession();
        var criteria = session.CreateMultiCriteria();

        //Find classes that inherit from BaseClass
        var classses = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.BaseType == typeof(BaseClass));
        var searchValue = "Test";

        foreach (var classs in classses)
        {
            //Find all the properties that are typeof string
            var properties = classs.GetProperties()
                                   .Where(x => x.PropertyType == typeof(string));

            var query = DetachedCriteria.For(classs);

            foreach (var memberInfo in properties)
            {
                query.Add(Restrictions.InsensitiveLike(memberInfo.Name, searchValue, MatchMode.Anywhere));
            }

            criteria.Add(query);
        }

        var results = criteria.List()
                              .Cast<ArrayList>()
                              .ToList()
                              .SelectMany(x => x.ToArray())
                              .Cast<BaseClass>()
                              .ToList();

        foreach (var result in results)
        {
            Console.WriteLine(result.Id);
        }

将像这样生成单个查询批处理:

SELECT this_.Id   as Id1_0_,
       this_.Name as Name1_0_
FROM   TestClassOne this_
WHERE  lower(this_.Name) like '%test%' /* @p0 */


SELECT this_.Id    as Id3_0_,
       this_.Value as Value3_0_,
       this_.Hobby as Hobby3_0_
FROM   TestClassTwo this_
WHERE  lower(this_.Value) like '%test%' /* @p1 */
       and lower(this_.Hobby) like '%test%' /* @p2 */


SELECT this_.Id    as Id2_0_,
       this_.Month as Month2_0_,
       this_.Day   as Day2_0_
FROM   TestClassThree this_
WHERE  lower(this_.Month) like '%test%' /* @p3 */


SELECT this_.Id      as Id0_0_,
       this_.Title   as Title0_0_,
       this_.Content as Content0_0_
FROM   TestClassFour this_
WHERE  lower(this_.Title) like '%test%' /* @p4 */
       and lower(this_.Content) like '%test%' /* @p5 */

【讨论】:

  • 这看起来很有希望。有机会我会去看看。谢谢!
  • 感谢您的帮助,这看起来正是我想要的。但是我收到了这个错误 - The driver NHibernate.Driver.OracleClientDriver does not support multiple queries.
  • @jjnguy - 天哪,这是 SQLServer 的一个功能,Oracle 不支持查询批处理 :( 那么你原来问题的答案是不可能的 :(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多