NHibernate - 使用一个查询查询多个表

时间:2011-04-28 14:20:18

标签: c# nhibernate criteria

我正在使用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>(); ;
}

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

1 个答案:

答案 0 :(得分:2)

此方法仅适用于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 */