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:
{
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: