0

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

我尝试这样做,但是当我GetValue()从 PropertyInfo 调用方法时,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,我怎么能用反射来做到这一点?!

4

3 回答 3

1

Any是一种扩展方法,所以如果你想找到它,请查看这篇文章: Reflection to identify Extension Methods

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

于 2013-05-15T20:50:24.260 回答
1

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

相反,如果您将您的集合映射到lazy="extra"您可以检查Count == 0(这是一种ICollection<T>方法,如果您使用dynamic.

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

于 2013-05-16T12:01:40.130 回答
0

您将 IQueryableAny()扩展方法与 IEnumerableAny()扩展方法混合在一起。

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

但是,如果您调用Any()实体内的持久集合,则只会执行扩展方法的代码。NHibernate 将其视为对集合的任何其他访问并加载整个集合。

于 2013-05-16T05:55:59.610 回答