如何使用反射从属性调用方法

本文关键字:调用 方法 从属性 反射 何使用 | 更新日期: 2023-09-27 18:13:40

我在应用程序中使用nhibernate,并且我有一个具有一些关系的映射模型。这些关系映射到List<T>,我需要将一个实体传递给一个方法,并调用Any()方法来检查每个关系上是否有寄存器。

我试着这样做,但是当我从PropertyInfo调用GetValue()方法时,NHibernate将加载一切,但我只需要调用Any()方法来提高性能,NHibernate将查询一个简单的查询来检查。我试试这个:

var type = entity.GetType();
foreach (var propertyInfo in type.GetProperties().Where(p => typeof (IEnumerable<>).IsAssignableFrom(p.PropertyType)))
{
   // it works, but load everything just to check if there are something...
   var collection = propertyInfo.GetValue(entity) as IEnumerable<dynamic>;
   if (collection != null)
      bool has = collection.Any();
}

我想在这里调用IEnumerable.Any(),但是我怎么能在没有GetValue的反射中做到这一点呢?

如何使用反射从属性调用方法

在集合上调用Enumerable.Any()将导致初始化,因为实现会读取是否有元素。

相反,如果你用lazy="extra"映射你的集合,你可以检查Count == 0(这是一个ICollection<T>方法,如果你使用dynamic,你可以很容易地调用它)。

你也可以安装NHibernate。CollectionQuery,使用可查询的集合类型映射你的集合,并调用collection.AsQueryable().Any()

Any是一个扩展方法,所以如果你想找到它,看看这篇文章:识别扩展方法的反思

但是Entity仍然会加载整个列表,因为Any方法需要整个列表来应用搜索模式(即使它是空的)。

您将IQueryable Any()扩展方法与IEnumerable Any()扩展方法混淆了。

如果你在NHibernate Linq查询中调用Any()(由session.Query<EntityType>()启动),NHibernate看到你只想知道是否有一个元素。它可以做到这一点,因为在这种情况下,您正在使用IQueryable的扩展方法,并创建一个表达式树,而不是执行扩展方法内的代码。

但是如果在实体内部的持久集合上调用Any(),这将只执行扩展方法的代码。NHibernate把这看作是对集合的任何其他访问,并加载整个集合。