8

Tengo un problema con NHibernate, no puedo encontrar ninguna solución para. En mi proyecto tengo una entidad simple (Batch), pero cada vez que intento ejecutar la siguiente prueba, obtengo una excepción. Tengo triede un par de maneras diferentes de realizar una consulta similar, pero una excepción casi idéntica para todos (difiere en qué método LINQ se está ejecutando).NHibernate (3.1.0.4000) NullReferenceException utilizando Query <> y NHibernate Facility

La primera prueba:

[Test] 
public void QueryLatestBatch() 
{ 
    using (var session = SessionManager.OpenSession()) 
    { 
     var batch = session.Query<Batch>() 
      .FirstOrDefault(); 

     Assert.That(batch, Is.Not.Null); 
    } 
} 

La excepción:

System.NullReferenceException : Object reference not set to an instance of an object. 
at NHibernate.Linq.NhQueryProvider.PrepareQuery(Expression expression, ref IQuery query, ref NhLinqExpression nhQuery) 
at NHibernate.Linq.NhQueryProvider.Execute(Expression expression) 
at System.Linq.Queryable.FirstOrDefault(IQueryable`1 source) 

La segunda prueba:

[Test] 
public void QueryLatestBatch2() 
{ 
    using (var session = SessionManager.OpenSession()) 
    { 
     var batch = session.Query<Batch>() 
      .OrderBy(x => x.Executed) 
      .Take(1) 
      .SingleOrDefault(); 

     Assert.That(batch, Is.Not.Null); 
    } 
} 

La excepción:

System.NullReferenceException : Object reference not set to an instance of an object. 
at NHibernate.Linq.NhQueryProvider.PrepareQuery(Expression expression, ref IQuery query, ref NhLinqExpression nhQuery) 
at NHibernate.Linq.NhQueryProvider.Execute(Expression expression) 
at System.Linq.Queryable.SingleOrDefault(IQueryable`1 source) 

Sin embargo, éste está pasando (usando QueryOver <>):

[Test] 
public void QueryOverLatestBatch() 
{ 
    using (var session = SessionManager.OpenSession()) 
    { 
     var batch = session.QueryOver<Batch>() 
      .OrderBy(x => x.Executed).Asc 
      .Take(1) 
      .SingleOrDefault(); 

     Assert.That(batch, Is.Not.Null); 
     Assert.That(batch.Executed, Is.LessThan(DateTime.Now)); 
    } 
} 

Utilizando el QueryOver <> API no está mal del todo, pero estoy sólo un poco desconcertado que la consulta <> API ISN' t funcionando, lo cual es algo triste, ya que la operación First() es muy concisa, y nuestros desarrolladores realmente disfrutan de LINQ.

Realmente espero que haya una solución para esto, ya que parece extraño que estos métodos fallen una prueba tan simple.

EDITAR

Estoy usando Oracle 11g, mis asignaciones se hacen con FluentNHibernate registrado a través del castillo de Windsor con el Fondo para NHibernate. Como escribí, lo curioso es que la consulta funciona perfectamente con QueryOver <> API, pero no a través de LINQ.

+0

Hay algo mal con sus asignaciones, configuración u otra parte de su código que no muestra, porque todos esos métodos funcionan bien para mí (y en las pruebas de NH) –

+0

Algo está muy mal con mi configuración. No puedo obtener ningún método en Query <> para que funcione ahora. Supongo que hay algo mal con mis referencias. – Siewers

+0

He encontrado cuál era el problema/es. Aparentemente estoy haciendo algo mal en NHibernateFacility, ya que es el que está causando todos los problemas. Si creo una fábrica de sesiones fuera de las instalaciones, puedo consultar utilizando Query <>, pero con ella, ¡no funciona! – Siewers

Respuesta

11

Hay un problema con la implementación actual de los extensionmethods LINQ para NHibernate 3.1.0.4000 se utiliza junto con NHibernate 2.0RC Facility (y versiones anteriores) (ver: https://nhibernate.jira.com/browse/NH-2626 y discusión aquí: http://groups.google.com/group/castle-project-devel/browse_thread/thread/ac90148a8d4c8477)

La solución que estoy utilizando en este momento es simplemente ignorar los métodos de extensión LINQ provistos por NHibernate y crearlos yo mismo. Son realmente tan sólo una sola línea:

public static class NHibernateLinqExtensions 
{ 
    /// <summary> 
    /// Performs a LINQ query on the specified type. 
    /// </summary> 
    /// <typeparam name="T">The type to perform the query on.</typeparam> 
    /// <param name="session"></param> 
    /// <returns>A new <see cref="IQueryable{T}"/>.</returns> 
    /// <remarks>This method is provided as a workaround for the current bug in the NHibernate LINQ extension methods.</remarks> 
    public static IQueryable<T> Linq<T>(this ISession session) 
    { 
     return new NhQueryable<T>(session.GetSessionImplementation()); 
    } 

    /// <summary> 
    /// Performs a LINQ query on the specified type. 
    /// </summary> 
    /// <typeparam name="T">The type to perform the query on.</typeparam> 
    /// <param name="session"></param> 
    /// <returns>A new <see cref="IQueryable{T}"/>.</returns> 
    /// <remarks>This method is provided as a workaround for the current bug in the NHibernate LINQ extension methods.</remarks> 
    public static IQueryable<T> Linq<T>(this IStatelessSession session) 
    { 
     return new NhQueryable<T>(session.GetSessionImplementation()); 
    } 
} 

Entonces, cuando tengo que hacer una consulta LINQ, sólo tiene que utilizar en lugar de session.Linq<EntityType>()session.Query<EntityType>.

Espero que ayude a alguien en la misma situación que yo.

+0

ayuda! gracias – Henrik

+0

Gracias! ¡Buen trabajo! – Kimi

Cuestiones relacionadas