2010-05-20 4 views
6

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

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» и «1», но результат по-прежнему остается пустым.

[EDIT]

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

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

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

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

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

Благодаря

+1

Не понимаю, почему не просто 'Restrictions.Eq (« DataField »,« True »)' –

+0

Вы правы. Для логического я мог бы легко пойти на сравнение строк, но для DateTime у меня такая же проблема, как и в bool, и там очень важно передать строку объекту DateTime –

+0

, почему у вас есть поле datetime, отображаемое как строка? –

ответ

5

К сожалению, то, что вы пытаетесь достичь будет трудно сделать, потому что это идет вразрез с зерном, что NHibernate и РСУБД пытается сделать для вас. Используя нетипизированные данные, вы обойдетесь в большую часть выигрышей, которые дает вам RDBM.

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

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

Altenratory вы можете иметь nHibernate для управления различными типами и позволить ему выполнять весь тяжелый подъем для вас. NHibernate можно сопоставить класс hiearchies к таблицам, так что вы могли бы создать объекты, как это:

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 возвращает DateProperty экземпляров.Вы также можете писать запросы, которые могут возвращать несколько типов, где статический тип - AbstractProperty. Затем вы можете использовать проверки visitor pattern или «is» на AbstractProperty, чтобы определить тип и применить конкретный тип для извлечения значения.

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

+0

Спасибо за отличный ответ. Я рассмотрю ваше решение! –

+1

Это то, что я бы тоже предложил; использование наследования в hibernate позволяет запрашивать любое общее свойство, но тогда вы можете иметь таблицу для каждого типа с соответствующим образом напечатанным столбцом в схеме. – RMorrisey