Как сравнить объект с прокси-объектом NHibernate?

Я использую Сравнить объекты .NET, чтобы проверить, правильно ли сохраняются мои POCO в тестовой базе данных. Возьмем пример POCO:

public class NoahsArk
{
    public virtual Noah Noah { get; set; }
}

И файл сопоставления с использованием FNH:

public class NoahsArkMap : ClassMap<NoahsArk>
{
    References(x => x.Noah).Cascade.All();
}

Теперь я запускаю этот код:

var noahsArk = new NoahsArk { new Noah() }; // create a new ark
var dbNoahsArk = database.SaveAndLoad(noahsArk); // saves the ark to the db and loads it again into another object
Assert.That(new CompareObjects().Compare(noahsArk, dbNoahsArk), Is.True); // will return true if all properties (including collections) are equal

Assert() терпит неудачу, потому что видит noahsArk.Noah как объект Noah, а dbNoahsArk.Noah как прокси-объект NHibernate. Я не знаю, что NHibernate делает в фоновом режиме, потому что если я сделаю это вместо этого:

Assert.That(noahsArk.Noah, Is.EqualTo(dbNoahsArk.Noah));

Он отлично работает, хотя оба типа объектов различаются, если я использую GetType() на обоих. У меня вопрос: как сделать так, чтобы NHibernate «прозрачно» возвращал объект вместо прокси, когда я пытаюсь использовать с ним Compare .NET Objects? Или Compare .NET Objects несовместим с NHib?

Дополнительная информация:

Я использую Compare .NET Objects, поэтому мне не нужно писать тесты на равенство для каждого свойства. Мои POCO, вероятно, придется изменить, и это очень поможет, если у меня будет инструмент, который может проводить глубокие сравнения с использованием Reflection.

Кроме того, я знаю, что могу сделать свойство не ленивой загрузкой, используя это в моем классе сопоставления:

References(x => x.Noah).Not.LazyLoad().Cascade.All();

Но для меня это был бы последний вариант, потому что он устраняет преимущества ленивой загрузки.


person Daniel T.    schedule 18.11.2009    source источник


Ответы (2)


Я считаю, что вам нужно переопределить GetHashCode и Equals в ваших объектах.

person James Gregory    schedule 19.11.2009
comment
Это то, что должно делать Compare .NET Objects, поэтому мне не нужно переопределять их в каждом POCO, а затем обновлять их всякий раз, когда POCO меняются. - person Daniel T.; 20.11.2009
comment
Я отметил ваш ответ как правильный, потому что мне очень нравится Fluent NHibernate :). Продолжайте хорошую работу! - person Daniel T.; 21.11.2009

Compare .NET Objects поступает правильно, поскольку экземпляры различаются (типы разные, это прокси, как вы сами говорите).

Что нам пришлось сделать в проекте, который использовал NHibernate несколько лет назад, так это реализовать наш собственный GetUnderlyingType () (имя, украденное из класса Enum) для нашей сущности «супертип уровня».

GetUnderlyingType () просто возвращает тип базового класса, если это прокси.

Затем этот метод использовался в нашем методе Equals () вместо GetType () (как используется в учебнике, R # и т. Д.).

person Martin R-L    schedule 19.11.2009
comment
Вы правы. Я решил проблему, загрузив исходный код для Compare .NET Objects и отключив проверку на равенство GetType (). Это означает, что вам нужно передать те же типы, иначе в какой-то момент будет выдано исключение, но я готов смириться с этим, учитывая, что я использую его только для сравнения POCO. - person Daniel T.; 21.11.2009
comment
Вот реализация: stackoverflow.com/questions/2664245/ - person Ricardo Stuven; 13.11.2011