NHibernate - запрос нескольких таблиц одним запросом - PullRequest
1 голос
/ 28 апреля 2011

Я использую 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 Ответ

2 голосов
/ 29 апреля 2011

Этот метод будет работать только с 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 */
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...