NHibernate QueryException:类型不匹配,期望类型==实际类型

时间:2010-01-13 22:35:46

标签: c# nhibernate

当使用ActiveRecord 2.0和NHibernate 2.1.0时,我们在Web应用程序中遇到了这个非常奇怪的问题(也尝试过2.1.2)。如果这个描述有点模糊,我很抱歉,但是我们在确切地了解发生了什么时遇到了问题。我们正在开发一个大型企业应用程序,我们正在尝试隔离问题并做一个小例子,但我们还没有完成这个。

当我们尝试对具有多对一关系的两个对象执行特殊查询时,会出现问题。这是导致问题的代码:

int testItemId = 1;
TestItem testItem = ActiveRecordMediator<TestItem>.FindByPrimaryKey(testItemId, false);
DetachedCriteria testCriteria = DetachedCriteria.For<TestItemRevision>();
testCriteria.Add(Expression.Eq("TestItem", testItem));
TestItemRevision testRevision = ActiveRecordMediator<TestItemRevision>.FindFirst(testCriteria);

执行FindFirst(或FindAll)时,抛出以下异常: NHibernate.Criterion.SimpleExpression中的类型不匹配:TestItem期望类型MyProduct.Core.DomainModel.Test.TestItem,实际类型MyProduct.Core.DomainModel.Test.TestItem

如您所见,期望的类型==实际类型。

我们发现NHibernate.Criterion.CriterionUtil.GetColumnNamesUsingPropertyName(...)中抛出了这个异常。我们已经编译了我们自己的NHibernate版本,这里有一些额外的日志记录。 当一切正常时,我们得到这个:

propertyType.ReturnedClass.Assembly: MyProduct.Core.DomainModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
propertyType.ReturnedClass.Assembly.Location: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\daa38103\4727b73f\assembly\dl3\bb8c85b9\7202540f_a593ca01\MyProduct.Core.DomainModel.DLL
value.GetType().Assembly: MyProduct.Core.DomainModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
value.GetType().Assembly.Location: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\daa38103\4727b73f\assembly\dl3\bb8c85b9\7202540f_a593ca01\MyProduct.Core.DomainModel.DLL

当抛出异常时,我们得到:

propertyType.ReturnedClass.Assembly: MyProduct.Core.DomainModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
propertyType.ReturnedClass.Assembly.Location == String.Empty: True
value.GetType().Assembly: MyProduct.Core.DomainModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
value.GetType().Assembly.Location: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\daa38103\4727b73f\assembly\dl3\bb8c85b9\7202540f_a593ca01\MyProduct.Core.DomainModel.DLL

即,抛出异常时,期望的类型没有Location,并被视为不同的程序集。

真正奇怪的是:异常并不总是被抛出。我们必须在IIS中回收应用程序池以重现问题,并且只有大约1/3的重启将实际触发它。我们认为这个查询必须是重启后发生的第一件事,但我们不确定这一点。抛出异常一次后,查询将无法再次运行,直到应用程序池被回收,或者bin文件夹中的DLL已更新。重新启动网站或更改Web.config没有帮助。我们在WinServer 2003 / IIS6和Win7 / IIS7.5上都重现了这个问题。

我们尝试使用完全相同的对象映射和完全相同的查询来设置测试项目,但是我们还没有能够在大型应用程序之外重现问题。有没有人知道可能会导致这样的事情?

修改

这是我们在global.asax Application_Start中加载程序集的方式:

Assembly[] assemblies = new[] { Assembly.Load("MyProduct.Core.DomainModel") };
ActiveRecordStarter.Initialize(assemblies, ActiveRecordSectionHandler.Instance);

(这是一个简化版本,我们真的从配置中加载我们的程序集名称,但它与此问题无关。)

1 个答案:

答案 0 :(得分:1)

MSDN says that, for the Assembly Location property,

  

如果从字节数组加载程序集,例如使用Load(array [])方法重载时,返回的值为空字符串(“”)。

也就是说,不是从磁盘上的文件位置加载程序集,而是有人读入一个字节数组并以这种方式加载它。 google-tubes告诉我这将导致程序集加载a different security context,因此,NHibernate会将其视为不同的类型并不奇怪。

您是否有可能以某种方式加载程序集,可能在某种竞争条件下?我试着从这里进入兔子洞。祝你好运!