2010-06-01 3 views
4

У меня была проблема с NHibernate, когда я забыл отобразить одно свойство класса.Как найти неотображаемые свойства в сопоставленном классе NHibernate?

очень упрощенный пример:

public class MyClass 
{ 
    public virtual int ID { get; set; } 
    public virtual string SomeText { get; set; } 
    public virtual int SomeNumber { get; set; } 
} 

... и файл отображения:

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
        assembly="MyAssembly" 
        namespace="MyAssembly.MyNamespace"> 

    <class name="MyClass" table="SomeTable"> 
     <property name="ID" /> 
     <property name="SomeText" />  
    </class> 

</hibernate-mapping> 

В этом простом примере, вы можете увидеть проблему сразу:
есть свойство названный «SomeNumber» в классе, но не в файле сопоставления.
Таким образом, NHibernate не будет отображать его, и он всегда будет равен нулю.

Настоящий класс имел намного больше свойств, поэтому проблему не так-то просто было увидеть, и мне потребовалось некоторое время, чтобы выяснить, почему SomeNumber всегда возвращал нуль, хотя я был на 100% уверен, что значение в базе данных было! = ноль.

Итак, вот мой вопрос:

Есть некоторые простой способ выяснить это с помощью NHibernate?
Как предупреждение компилятора при сопоставлении класса, но некоторые из его свойств отсутствуют.
Или какой-то запрос, который я могу запустить, который показывает мне unmapped свойства в сопоставленных классах ... вы получаете идею.

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

EDIT:
Хорошо, я смотрел на все, что предложенная и решил идти с API метаданных ... это выглядит проще всего для меня.
Теперь, когда я знаю, что искать, я нашел несколько примеров, которые помогли мне начать работу.
До сих пор у меня есть это:

Type type = typeof(MyClass); 

IClassMetadata meta = MySessionFactory.GetClassMetadata(type); 

PropertyInfo[] infos = type.GetProperties(); 

foreach (PropertyInfo info in infos) 
{ 
    if (meta.PropertyNames.Contains(info.Name)) 
    { 
     Console.WriteLine("{0} is mapped!", info.Name); 
    } 
    else 
    { 
     Console.WriteLine("{0} is not mapped!", info.Name); 
    } 
} 

Она почти работает, за исключением одной вещи: IClassMetadata.PropertyNames возвращает имена всех свойств кроме идентификатор.
Чтобы получить идентификатор, мне нужно использовать IClassMetadata.IdentifierPropertyName.

Да, я мог бы сохранить .PropertyNames в новом массиве, добавить .IdentifierPropertyName к нему и выполнить поиск , что массив.
Но это выглядит странно для меня.
Нет ли лучшего способа получить все отображенные свойства, включая ID?

+0

Именно по этой причине я написал «тестер отображения». Но это довольно много кода. он проверяет, может ли объект быть сохранен и извлечен без потери данных. Может быть, я получу прием и найду время, чтобы выпустить его когда-нибудь. –

+0

+1 для показа мне, как получить идентификатор имя_пользователя. Именно то, что я искал! –

ответ

5

Вы можете использовать API метаданных NHibernate, чтобы найти отображаемые свойства и отражение, чтобы найти все свойства.

Редактировать Нет, нет другого способа перечислить все свойства, включая идентификатор.Это не так сложно использовать:

foreach (PropertyInfo info in infos) 
{ 
    if (meta.PropertyNames.Contains(info.Name) || info.Name = meta.IdentifierPropertyName) 
    { 
     Console.WriteLine("{0} is mapped!", info.Name); 
    } 
    else 
    { 
     Console.WriteLine("{0} is not mapped!", info.Name); 
    } 
} 
+0

Мы делаем это, это происходит только один раз в app-init и дамп результатов в журнале – Jaguar

+0

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

+0

О да, вы правы - это действительно просто. Жаль, что я сам об этом не думал :-) –

1

Есть два инструмента, я знаю, что может помочь с этим:

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