如何使用Reflection从属性调用方法

时间:2013-05-15 20:42:41

标签: c# linq nhibernate reflection collections

我在应用程序中使用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的情况下使用反射来做到这一点?!

3 个答案:

答案 0 :(得分:1)

Any是一种扩展方法,因此如果您想查找它,请查看此帖子: Reflection to Identify Extension Methods

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

答案 1 :(得分:1)

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

相反,如果您使用lazy="extra"映射收藏集,则可以检查Count == 0(这是ICollection<T>方法,如果您使用dynamic,则可以轻松调用它。

或者,您可以安装NHibernate.CollectionQuery,使用可查询的集合类型映射您的集合,然后调用collection.AsQueryable().Any()

答案 2 :(得分:0)

您正在将IQueryable Any()扩展方法与IEnumerable Any()扩展方法混合使用。

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

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