приведение строки к bool с использованием nHibernate Criteria - PullRequest
6 голосов
/ 20 мая 2010

У меня есть запрос nHibernate с использованием Criteria, и я пытаюсь привести строку к bool в самом запросе. Я сделал то же самое с приведением строки к int, и это хорошо работает (свойство DataField имеет значение «1» как строка):

var result = Session
   .CreateCriteria<Car>()
   .Add(Restrictions.Eq((Projections.Cast(NHibernateUtil.Int32,
    Projections.Property("DataField"), 1))
   .List<Car>();

tx.Commit();

Но я пытаюсь сделать то же самое с bool, но я не получаю ожидаемый результат:

var result = Session
   .CreateCriteria<Car>()
   .Add(Restrictions.Eq((Projections.Cast(NHibernateUtil.bool,
    Projections.Property("DataField"), true))
   .List<Car>();

tx.Commit();

«DataField» - это строка «True», но в результате получается пустой список, где он должен содержать 100 элементов со строкой свойства «DataField», установленной в «True». Я пробовал со строками "true" и "1", но в результате все еще пустой список.

[EDIT]

Как прокомментировано ниже, я мог бы проверить строку "True" или "False", но я бы сказал, что это более общий вопрос, чем просто для логического значения.

Обратите внимание, что идея состоит в том, чтобы иметь какое-то представление значения ключа для данных, где значением могут быть разные типы данных. Мне нужно, чтобы таблица значений содержала все данные, поэтому хранение данных в виде строки кажется самым чистым решением!

Мне удалось использовать описанный выше метод для хранения как int, так и double как строки, так и для преобразования в запросе, но мне не удалось использовать один и тот же метод для DateDime и Boolean.

А для DateTime крайне важно иметь фактический объект DateTime.

Как я могу заставить приведение из строки в bool и строку в DateTime работать в запросах?

Спасибо

1 Ответ

5 голосов
/ 23 мая 2010

К сожалению, то, что вы пытаетесь достичь, будет трудно сделать, потому что это идет вразрез с тем, что nHibernate и RDBM пытаются сделать для вас. Используя нетипизированные данные, вы будете обходить многие выгоды, которые дает вам использование RDBM.

Без полной схемы я могу только догадываться. Как вы узнаете, какой тип поля является правильным? Я предполагаю, что у вас есть столбец типа, который указывает, является ли значение целым, логическим, датой и т. Д. Если вы это сделаете, продолжите со столбцом идентификатора типа, а также отдельным столбцом для каждого типа данных. Это не сложнее, чем то, что вы делаете, поскольку для каждого типа данных уже есть отдельные запросы, и вы получаете ясность, проверку типов и возможность индексации.

Если вы хотите защититься от возможности определения более одного значения (то есть значений в столбцах с несколькими типами), вы можете создать ограничение для таблицы, которое проверяет, что каждая строка определяет значение не более чем для одного типа данных. (Вы также можете проверить, что столбец для указанного типа не является нулевым, если это подходит для вашего случая.)

В качестве альтернативы вы можете использовать nHibernate для управления различными типами и позволить ему выполнять всю тяжелую работу за вас. nHibernate может отображать иерархии классов в таблицы, поэтому вы можете создавать такие объекты, как это:

public class AbstractProperty
{
   // concrete name - persisted
   public String Name { get; set; etc.. }

   // owner property as well?

   // abstract value provided by subclasses. This property is not persisted.
   // used simply to provide polymorphic access to the value.
   public abstract Object Value { get; set; }
}

public class DateProperty : AbstractProperty
{
   // concrete date property
   public Date date { get; set; etc.. } 

   // value delegates to date property
   public Object value { get; set; }
}

С этой схемой у вас есть возможность получить значения с определенным типом данных, где, например, запрос использует сущность DateProperty, значение explicity возвращает DateProperty экземпляров. Вы также можете писать запросы, которые могут возвращать несколько типов, где статический тип - AbstractProperty. Затем вы можете использовать шаблон посетителя или проверки 'is' в AbstractProperty, чтобы определить тип и привести к конкретному типу для извлечения значения.

Гуру nHibernate может помочь вам исправить приведение, но в долгосрочной перспективе я рекомендую использовать реальные типы данных в вашей базе данных. Это избавит вас от головной боли позже.

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