Как правильно выполнить поиск с помощью nhibernate? - PullRequest
1 голос
/ 27 мая 2010

Я работаю над небольшим проектом, который должен обеспечивать базовый поиск в базе данных. В настоящее время я использую nhibernate для взаимодействия с базой данных. В базе данных у меня есть 2 таблицы: персона и адрес. Таблица Person имеет отношение «многие к одному» с Address.

Код, который я придумал для поиска:

public IList<T> GetByParameterList(List<QueryParameter> parameterList)
    {
        if (parameterList == null)
        {
            return GetAll();
        }
        using (ISession session = NHibernateHelper.OpenSession())
        {
            ICriteria criteria = session.CreateCriteria<T>();
            foreach (QueryParameter param in parameterList)
            {
                switch (param.Constraint)
                {
                    case ConstraintType.Less:
                        criteria.Add(Expression.Lt(param.ParameterName, param.ParameterValue));
                        break;
                    case ConstraintType.More:
                        criteria.Add(Expression.Gt(param.ParameterName, param.ParameterValue));
                        break;
                    case ConstraintType.LessOrEqual:
                        criteria.Add(Expression.Le(param.ParameterName, param.ParameterValue));
                        break;
                    case ConstraintType.EqualOrMore:
                        criteria.Add(Expression.Ge(param.ParameterName, param.ParameterValue));
                        break;
                    case ConstraintType.Equals:
                        criteria.Add(Expression.Eq(param.ParameterName, param.ParameterValue));
                        break;
                    case ConstraintType.Like:
                        criteria.Add(Expression.Like(param.ParameterName, param.ParameterValue));
                        break;
                }
            }

            try
            {
                IList<T> result = criteria.List<T>();
                return result;
            }
            catch
            {
                //TODO: Implement some exception handling
                throw;
            }
        }
    }

Параметр запроса является вспомогательным объектом, который я использую для создания критериев и отправки его в dal, он выглядит следующим образом:

public class QueryParameter
{
    public QueryParameter(string ParameterName, Object ParameterValue, ConstraintType constraintType)
    {
        this.ParameterName = ParameterName;
        this.ParameterValue = ParameterValue;
        this.Constraint = constraintType;
    }

    public string ParameterName
    {
        get;
        set;
    }

    public Object ParameterValue
    {
        get;
        set;
    }

    public ConstraintType Constraint
    {
        get;
        set;
    }
}

Теперь это работает хорошо, если я выполняю поиск, например FirstName = "John", но не тогда, когда пытаюсь задать параметр, например Street = "Some Street". Похоже, что nhibernate ищет столбец улиц в таблице Person, но не в таблице Address.

Есть идеи, как мне изменить свой код, чтобы я мог правильно выполнить поиск? Подсказки? Может быть, какие-нибудь альтернативы?

Отказ от ответственности: я своего рода нуб, поэтому, пожалуйста, будьте нежны;) Спасибо, Денис.

Ответы [ 4 ]

1 голос
/ 01 июня 2010

Я бы сделал строго типизированный класс поиска для каждого моего класса объектов домена (например, используя генерацию кода для моих объектов домена).

Я хотел бы иметь абстрактный класс для размещения логики ICriteriaBuilder, использующей что-то очень близкое к вашему текущему коду, а затем рекурсивное для любого внутреннего свойства ICriteriaBuilder.

У меня был бы такой псевдокод:

class SearchCriteriaBuilder
public ConstraintType constraintType
public ICriteria Build(ISearchCriteriaBuilder pSearchCriteria)
{'your code goes there'}

class AdressSearchCriteriaBuilder : SearchCriteriaBuilder
public StringSearchCriteriaBuilder street;
public IntegerSearchCriteriaBuilder number;

class PersonSearchCriteriaBuilder : SearchCriteriaBuilder
public StringSearchCriteriaBuilder name;
public AdressSearchCriteriaBuilder adress;
0 голосов
/ 06 июня 2010

Посмотрите это видео в 1:57: http://skillsmatter.com/podcast/open-source-dot-net/nhibernate-tutorial-by-ayende-rahien

Айенде (самый известный эксперт по nhibernate) расскажет вам, как создавать динамические запросы, используя критерии api.

Следите заобъяснение foreach в 2: 04: 30

0 голосов
/ 27 мая 2010

Он ищет свойство Street в сущности Person (обратите внимание на язык ORM ... нет таблиц и столбцов ;-)) из-за этой строки:

ICriteria criteria = session.CreateCriteria<T>();

Я предполагаю, что ваш тип T это Person, и поэтому ваши критерии предполагают, что добавляемые вами ограничения относятся к свойствам в Person.

Если вы передаете параметр, который, как вам известно, является фильтром для объекта «Адрес», вам необходимо вызвать CreateAlias(...), чтобы «присоединиться» к этому адресу.

0 голосов
/ 27 мая 2010

Вы можете использовать hql-запрос, подобный этому

from Person p join Address a where a.Street = :street

И установить параметр: street с помощью запроса.

Я обнаружил, что использовать hql намного проще, чем иметь дело с критериями, особенно когда вы новичок. Ваш первый инстинкт - стандартизировать использование nhibernate, но пока вы изучаете его, лучше держать свой код близко к API nhibernate и не писать слишком много вспомогательных методов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...