Я пытаюсь написать метод Compare для сравнения свойств в некоторых POCO, используя Reflection, чтобы убедиться, что они были правильно сохранены в базе данных. Например, скажем, у меня есть это POCO:
public class NoahsArk
{
public string Owner { get; set; }
public ICollection<Animal> Animals { get; set; }
}
Что я хочу сделать, это:
[Test]
public class Saves_Correctly_To_Database()
{
var noahsArk = new NoahsArk { // some setup code here };
db.Save(noahsArk);
var dbNoahsArk = db.Get<NoahsArk>(noahsArk.Id);
Assert.That(Compare(noahsArk, dbNoahsArk), Is.True);
}
ORM, который я использую, это NHibernate. Мой метод сравнения выглядит так:
public static bool EqualsProperties<T>(this T x, T y)
{
var xType = x.GetType();
foreach (var property in xType.GetProperties())
{
if (property.GetValue(x, null).Implements(typeof(ICollection<>)))
{
var xValue = property.GetValue(x, null) as ICollection<T>;
var yValue = property.GetValue(y, null) as ICollection<T>;
}
Object.Implements()
- это метод расширения, который я написал, чтобы определить, реализует ли тип интерфейс. Как видите, метод неполный. Проблема, с которой я сталкиваюсь, заключается в том, что когда я использую property.GetValue(x, null)
, он возвращает object
, и я не знаю, как привести его к определенному универсальному типу ICollection
. Я должен быть в состоянии сделать это, чтобы я мог использовать LINQ, чтобы сделать x.Contains(y)
, чтобы сравнить две коллекции на равенство. Есть идеи, как это сделать?
P.S. Я пытался использовать Сравнить объекты .NET , но это дает мне исключение нулевой ссылки где-то глубоко внутри NHibernate. Он не правильно обрабатывает, как NHibernate прокси ICollection
для отложенной загрузки. Что еще хуже, NHibernate модифицирует POCO для поддержки отложенной загрузки, но все это делается во время выполнения. В исходном коде похоже, что вы просто работаете с обычным ICollection
, но NHibernate меняет это значение на NHibernate.Collections.Generic.PersistentSet
во время выполнения, и именно это приводит к сбою компаратора.