Sunday, January 22, 2012

Querying an Uninitialized Collection with NHibernate

I have talked before about the problem of accessing an uninitialized collection and presented a solution that allows us to see if the collection contains elements on the DB, and how many there are, without actually loading them. Now I have a general purpose solution for querying the collection on the DB.

Here it is:

public static IQueryable<T> Query<T>(this IEnumerable<T> collection)
{
    if (collection is AbstractPersistentCollection)
    {
        IPersistentCollection col = collection as IPersistentCollection;
 
        if (col.WasInitialized == false)
        {
            String role = col.Role;
            Object owner = col.Owner;
            Object key = col.Key;
            ISessionImplementor sessionImpl = typeof(AbstractPersistentCollection).GetField("session", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(collection) as ISessionImplementor;
            ISession session = sessionImpl as ISession;
            ISessionFactory sessionFactory = session.SessionFactory;
            String ownerEntityName = sessionImpl.BestGuessEntityName(owner);
            Type ownerType = Type.GetType(ownerEntityName);
            IClassMetadata metadata = sessionFactory.GetClassMetadata(ownerEntityName);
            String idPropertyName = metadata.IdentifierPropertyName;
            MethodInfo ownerIdGetMethod = ownerType.GetProperty(idPropertyName).GetGetMethod();
            String childPropertyName = role.Split('.').Last();
            MethodInfo ownerChildGetMethod = ownerType.GetProperty(childPropertyName).GetGetMethod();
            Type childType = typeof(T);
            ParameterExpression a = null;
            IQueryable<T> details = typeof(Queryable).GetMethods(BindingFlags.Static | BindingFlags.Public).Where(x => x.Name == "SelectMany" && x.GetParameters().Length == 2).First().MakeGenericMethod(ownerType, childType).Invoke
            (
                null,
                new Object[]
                    {                   
                        typeof(Queryable).GetMethods(BindingFlags.Static | BindingFlags.Public).Where(x => x.Name == "Where").First().MakeGenericMethod(ownerType).Invoke
                        (

Read more: Development With A Dot
QR: querying-an-uninitialized-collection-with-nhibernate.aspx

Posted via email from Jasper-Net