У нас есть эта очень странная проблема в веб-приложении при использовании ActiveRecord 2.0 с NHibernate 2.1.0 (также пробовали 2.1.2). Прошу прощения, если это описание немного расплывчато, но у нас возникают проблемы с пониманием того, что происходит. Мы работаем над большим корпоративным приложением, где мы пытаемся изолировать проблему и сделать небольшой пример, но мы еще этого не сделали.NHibernate QueryException: Тип несоответствие, ожидаемый тип == фактический тип
Проблема возникает, когда мы пытаемся выполнить специальный запрос по двум объектам со многими отношениями-к-одному. Это код, который будет вызывать эту проблему:
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
Т.е., когда исключение, ожидаемый тип не имеет Место и рассматривается как другая сборка.
Действительно странно то, что исключение не всегда выбрасывается. Мы должны переработать пул приложений в IIS, чтобы воспроизвести проблему, и только около 1 из 3 перезапуска действительно вызовут ее. Мы считаем, что этот запрос должен быть первым, что происходит после перезагрузки, но мы не уверены в этом. После того, как исключение будет отправлено один раз, запрос не будет работать снова до тех пор, пока пул приложений не будет повторно использован, или DLL в папке bin не будет обновлена. Перезапуск веб-сайта или изменение Web.config не помогают. Мы воспроизвели эту проблему как на WinServer 2003/IIS6, так и на Win7/IIS7.5.
Мы попытались настроить тестовый проект с точно такими же сопоставлениями объектов и одним и тем же запросом, но мы еще не смогли воспроизвести проблему за пределами большого приложения. Кто-нибудь знает, что может вызвать что-то подобное?
Edit:
Это, как мы загружаем нашу сборку, в global.asax Application_Start:
Assembly[] assemblies = new[] { Assembly.Load("MyProduct.Core.DomainModel") };
ActiveRecordStarter.Initialize(assemblies, ActiveRecordSectionHandler.Instance);
(Это упрощенная версия, мы действительно загружаются наши имена сборки из конфигурации , но это не имеет отношения к этой проблеме.)
Спасибо за ответ! Мы не загружаем сборку из массива байтов, мы загружаем ее по имени. К этому вопросу добавлена информация о загрузке. –
Хм. Вы можете проверить «Местоположение» в Application_Start? Если это правильно, то я задаюсь вопросом, происходит ли что-то странное с генерацией прокси ... –
Мы ошибались: мы использовали Load (Byte []), и это, вероятно, было гоночным. В дополнение к загрузке сборок при инициализации ActiveRecord мы также регистрировали пользовательский VirtualPathProvider. При инициализации этого провайдера мы загружали некоторые из тех же сборок из массива байтов. Я не знаю точно, когда инфраструктура ASP.NET инициализирует провайдера, но это, вероятно, было условием гонки между инициализацией ActiveRecord и VirtualPathProvider. Небольшая очистка сборки загрузила проблему :-) –