如何使用反射从属性调用方法
本文关键字:调用 方法 从属性 反射 何使用 | 更新日期: 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把这看作是对集合的任何其他访问,并加载整个集合。