简体   繁体   中英

How to call a method from of a property using Reflection

I'm using nhibernate in a application and I have a mapped model with some relations. Theses relations are mapping with List<T> and I need to pass a entity to a method and call the Any() method to check if there are registers on each relation.

I try to do it but when I call GetValue() method from a PropertyInfo the NHibernate will load everything, but I need just to call Any() method to improve the performance and nhibernate will query a simple query just to check. I try this:

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();

}

I would like to call IEnumerable.Any() here, but how can I do this with reflection without GetValue?!

Any is an extension method, so if you want to find it, check this post: Reflection to Identify Extension Methods

But Entity will still load the entire list, since the Any method needs the whole list to apply a search pattern (even if it is empty).

Calling Enumerable.Any() on a collection will cause initialization because the implementation reads to see if there are elements.

In contrast, if you map your collection with lazy="extra" you can check for Count == 0 (it's an ICollection<T> method, you can call it easily if you use dynamic .

Alternatively, you can install NHibernate.CollectionQuery , map your collections using the queryable collection types, and call collection.AsQueryable().Any() .

You are mixing up the IQueryable Any() extension method with the IEnumerable Any() extension method.

If you call Any() in a NHibernate Linq query (started by session.Query<EntityType>() ) NHibernate sees that you only want to know if there is one element. It can do this because in that case you are using the extension method of IQueryable and are creating an expression tree instead of executing the code inside the extension method.

But if you call Any() on an persistent collection inside an entity this will just execute the code of the extension method. NHibernate sees this like any other access to the collection and loads the whole collection.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM