Как найти несопоставленные свойства в сопоставленном классе NHibernate? - PullRequest
4 голосов
/ 01 июня 2010

У меня только что была проблема, связанная с 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?
Как предупреждение компилятора, когда класс отображается, но некоторые его свойства не являются.
Или какой-то запрос, который я могу выполнить, который показывает мне несопоставленные свойства в сопоставленных классах ... вы поняли.

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

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 и найти в этом массиве.
Но это выглядит странно для меня.
Нет ли лучшего способа получить все сопоставленных свойств, включая идентификатор?

Ответы [ 2 ]

6 голосов
/ 01 июня 2010

Вы можете использовать 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);
    }
}
1 голос
/ 01 июня 2010

Мне известны два инструмента, которые могут помочь с этим:

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

...