我在应用程序中使用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的情况下使用反射来做到这一点?!
答案 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看到这就像对集合的任何其他访问一样,并加载整个集合。