我有NHibernate的问题,我似乎无法找到任何解决方案。 在我的项目中,我有一个简单的实体(批处理),但每当我尝试运行以下测试时,我都会遇到异常。 我已经尝试了几种不同的方法来执行类似的查询,但几乎完全相同的异常(它与执行的LINQ方法不同)。
第一次测试:
[Test]
public void QueryLatestBatch()
{
using (var session = SessionManager.OpenSession())
{
var batch = session.Query<Batch>()
.FirstOrDefault();
Assert.That(batch, Is.Not.Null);
}
}
例外:
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)
第二次测试:
[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);
}
}
例外:
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)
但是,这个传递(使用QueryOver&lt;&gt;):
[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));
}
}
使用QueryOver&lt;&gt; API一点都不差,但我有点困惑的是查询&lt;&gt; API不起作用,这有点令人难过,因为First()操作非常简洁,我们的开发人员真的很喜欢LINQ。
我真的希望有一个解决方案,因为如果这些方法没有通过如此简单的测试,这似乎很奇怪。
修改
我正在使用Oracle 11g,我的映射是通过使用NHibernate Facility在Castle Windsor注册的FluentNHibernate完成的。 正如我所写,奇怪的是查询与QueryOver&lt;&gt;完美配合。 API,但不是通过LINQ。
答案 0 :(得分:11)
NHibernate 3.1.0.4000的LINQ扩展方法的当前实现存在一个问题,该方法与NHibernate Facility 2.0RC(和以前的版本)一起使用(参见:https://nhibernate.jira.com/browse/NH-2626并在此讨论:http://groups.google.com/group/castle-project-devel/browse_thread/thread/ac90148a8d4c8477)
我目前使用的修复方法是简单地忽略NHibernate提供的LINQ扩展方法并自己创建它。他们真的只是单行:
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());
}
}
然后,当我需要进行LINQ查询时,我只使用session.Linq<EntityType>()
代替session.Query<EntityType>
。
希望它可以帮助处于同样情况的人。
答案 1 :(得分:0)
我找到了以下内容:http://groups.google.com/group/castle-project-users/browse_thread/thread/5efc9f3b7b5d6a08
显然当前版本的NHibernate Facility和NHibernate 3.1.0.4000存在问题。
我想我只需等待修复:)