我正在尝试编写一个比较方法来使用反射比较某些 POCO 中的属性,以确保它们已正确保存到数据库中。例如,假设我有这个 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)
比较两个集合是否相等。关于如何做到这一点的任何想法?
PS 我尝试使用Compare .NET Objects,但它在 NHibernate 的某个深处给了我一个空引用异常。它没有正确处理 NHibernate 如何代理ICollection
延迟加载。更糟糕的是,NHibernate 修改了 POCO 以支持延迟加载,但这都是在运行时完成的。在源代码中,看起来您只是在使用常规的ICollection
,但 NHibernate 在运行时将其更改为NHibernate.Collections.Generic.PersistentSet
,这就是导致比较器失败的原因。