Checking if an Unloaded Collection Contains Elements

Posted by Ricardo Peres on ASP.net Weblogs See other posts from ASP.net Weblogs or by Ricardo Peres
Published on Mon, 14 Nov 2011 16:05:45 GMT Indexed on 2011/11/14 17:52 UTC
Read the original article Hit count: 284

Filed under:
|
|

If you want to know if an unloaded collection in an entity contains elements, or count them, without actually loading them, you need to use a custom query; that is because the Count property (if the collection is not mapped with lazy=”extra”) and the LINQ Count() and Any() methods force the whole collection to be loaded.

You can use something like these two methods, one for checking if there are any values, the other for actually counting them:

   1: public static Boolean Exists(this ISession session, IEnumerable collection)
   2: {
   3:     if (collection is IPersistentCollection)
   4:     {
   5:         IPersistentCollection col = collection as IPersistentCollection;
   6:  
   7:         if (col.WasInitialized == false)
   8:         {
   9:                 String[] roleParts = col.Role.Split('.');
  10:                 String ownerTypeName = String.Join(".", roleParts, 0, roleParts.Length - 1);
  11:                 String ownerCollectionName = roleParts.Last();
  12:                 String hql = "select 1 from " + ownerTypeName + " it where it.id = :id and exists elements(it." + ownerCollectionName + ")";
  13:                 Boolean exists = session.CreateQuery(hql).SetParameter("id", col.Key).List().Count == 1;
  14:  
  15:                 return (exists);
  16:         }
  17:     }
  18:  
  19:     return ((collection as IEnumerable).OfType<Object>().Any());
  20: }
  21:  
  22: public static Int64 Count(this ISession session, IEnumerable collection)
  23: {
  24:     if (collection is IPersistentCollection)
  25:     {
  26:         IPersistentCollection col = collection as IPersistentCollection;
  27:  
  28:         if (col.WasInitialized == false)
  29:         {
  30:             String[] roleParts = col.Role.Split('.');
  31:             String ownerTypeName = String.Join(".", roleParts, 0, roleParts.Length - 1);
  32:             String ownerCollectionName = roleParts.Last();
  33:             String hql = "select count(elements(it." + ownerCollectionName + ")) from " + ownerTypeName + " it where it.id = :id";
  34:             Int64 count = session.CreateQuery(hql).SetParameter("id", col.Key).UniqueResult<Int64>();
  35:  
  36:             return (count);
  37:         }
  38:     }
  39:  
  40:     return ((collection as IEnumerable).OfType<Object>().Count());
  41: }

Here’s how:

   1: MyEntity entity = session.Load(100);
   2:  
   3: if (session.Exists(entity.SomeCollection))
   4: {
   5:     Int32 count = session.Count(entity.SomeCollection);
   6:     //...
   7: }

© ASP.net Weblogs or respective owner

Related posts about .NET

Related posts about nhibernate