2009-04-28 3 views
0

Я получаю «ArgumentOutOfRangeException» при индексе параметров всякий раз, когда пытаюсь создать экземпляр фабрики сеансов в nHibernate. Ошибка исходит из процедуры, находящейся в глубине недр. Я могу опубликовать трассировку стека ошибки, если это поможет.Ошибка создания SessionFactory в nHibernate

Это новый проект с довольно простой трехуровневой архитектурой. Уровень данных сопоставляет классы nHibernate с простыми интерфейсами, которые реализуются бизнес-уровнем. В настоящее время в nHibernate используется только один набор интерфейсов и файл сопоставления. Надеюсь, моя проблема легко заметить.

Вот функция, в которой я создаю sessionFactory.

Private Shared Function SessionFactory() As ISessionFactory 
     If _sessionFactory Is Nothing Then 
      Dim config As New NHibernate.Cfg.Configuration 
      config.Configure() 
      config.AddClass(GetType(ICompanyProperty)) 
      _sessionFactory = config.BuildSessionFactory    
     End If 
     Return _sessionFactory 
    End Function 

Вот мой hibernate.cfg.xml

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"> 
    <session-factory> 
    <property name="connection.provider"> 
     NHibernate.Connection.DriverConnectionProvider  
    </property> 
    <property name="dialect"> 
     NHibernate.Dialect.MsSql2005Dialect 
    </property> 
    <property name="connection.driver_class"> 
     NHibernate.Driver.SqlClientDriver 
    </property> 
    <property name="connection.connection_string"> 
     Data Source=dataserver.domain.ad;Initial Catalog=LABs;Integrated Security=SSPI 
    </property> 
    </session-factory> 
</hibernate-configuration> 

И файл отображения интерфейса я являюсь отображение.

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Sample.Data" namespace="Sample.Data"> 
    <class name="ICompanyProperty" table="CompanyProperty"> 
    <id name="CompanyPropertyID" column="CompanyPropertyID"> 
     <generator class="native" /> 
    </id>  
    <discriminator column="PropertyType" type="String" /> 
    <property name="CompanyID" /> 
    <property name="PropertyName" />  
    <subclass discriminator-value="SQL" name="ISQLLookupCompanyProperty"> 
     <property name="TableName" />  
     <property name="KeyField" /> 
     <property name="ValueField" /> 
     <property name="ConnectionString" /> 
    </subclass> 
    <subclass discriminator-value="LIST" name="ILookupCompanyProperty" />  
    </class> 
</hibernate-mapping> 

И интерфейсы

Public Interface ICompanyProperty 
    Property CompanyPropertyID() As Integer 
    Property PropertyName() As String 
    Property CompanyID() As Integer 
    Property PropertyType() As String 
End Interface 

Public Interface ILookupCompanyProperty 
    Inherits ICompanyProperty 
End Interface 

Public Interface ISQLLookupCompanyProperty 
    Inherits ILookupCompanyProperty 

    Property TableName() As String 
    Property KeyField() As String 
    Property ValueField() As String 
    Property ConnectionString() As String 
End Interface 

Спасибо!

Редактировать: запрашивалась функция stacktrace. вот от моего вызова фабрики сессий сборки до ошибки.

at System.Collections.ArrayList.get_Item(Int32 index) 
at NHibernate.SqlCommand.InFragment.ToFragmentString() 
at NHibernate.Persister.Entity.SingleTableEntityPersister.DiscriminatorFilterFragment(String alias) 
at NHibernate.Persister.Entity.SingleTableEntityPersister.FilterFragment(String alias) 
at NHibernate.Persister.Entity.AbstractEntityPersister.FilterFragment(String alias, IDictionary`2 enabledFilters) 
at NHibernate.Loader.Entity.EntityJoinWalker..ctor(IOuterJoinLoadable persister, String[] uniqueKey, Int32 batchSize, LockMode lockMode, ISessionFactoryImplementor factory, IDictionary`2 enabledFilters) 
at NHibernate.Loader.Entity.EntityLoader..ctor(IOuterJoinLoadable persister, String[] uniqueKey, IType uniqueKeyType, Int32 batchSize, LockMode lockMode, ISessionFactoryImplementor factory, IDictionary`2 enabledFilters) 
at NHibernate.Loader.Entity.EntityLoader..ctor(IOuterJoinLoadable persister, Int32 batchSize, LockMode lockMode, ISessionFactoryImplementor factory, IDictionary`2 enabledFilters) 
at NHibernate.Loader.Entity.EntityLoader..ctor(IOuterJoinLoadable persister, LockMode lockMode, ISessionFactoryImplementor factory, IDictionary`2 enabledFilters) 
at NHibernate.Loader.Entity.BatchingEntityLoader.CreateBatchingEntityLoader(IOuterJoinLoadable persister, Int32 maxBatchSize, LockMode lockMode, ISessionFactoryImplementor factory, IDictionary`2 enabledFilters) 
at NHibernate.Persister.Entity.AbstractEntityPersister.CreateEntityLoader(LockMode lockMode, IDictionary`2 enabledFilters) 
at NHibernate.Persister.Entity.AbstractEntityPersister.CreateEntityLoader(LockMode lockMode) 
at NHibernate.Persister.Entity.AbstractEntityPersister.CreateLoaders() 
at NHibernate.Persister.Entity.AbstractEntityPersister.PostInstantiate() 
at NHibernate.Persister.Entity.SingleTableEntityPersister.PostInstantiate() 
at NHibernate.Impl.SessionFactoryImpl..ctor(Configuration cfg, IMapping mapping, Settings settings, EventListeners listeners) 
at NHibernate.Cfg.Configuration.BuildSessionFactory() 

Edit2: Когда я удаляю дискриминатор, я больше не получаю эту ошибку. Разве я не делаю это правильно?

Редактирование 3: Когда я загружаю исходный код для nHibernate, создайте его самостоятельно, подключитесь к его отладчивому выводу и запустите его, я получаю совершенно другую ошибку о том, что ProxyFactoryFactory не настроен.

+0

Трассировка стека действительно поможет. – Rashack

+0

Просто прочитайте комментарии к ответу Джейми Ида (который, я думаю, в любом случае ошибочен). Я не знаю, чего вы на самом деле пытаетесь достичь. Но NH работает очень хорошо в трехъярусных архитектурах, поскольку он может отсоединять и повторно присоединять экземпляры с сеанса. Интерфейсы отображения также должны быть легкими. Не понимаю, зачем вам нужна какая-либо бизнес-логика на уровне доступа к данным. –

ответ

1

Я думаю, вам нужно сообщить NHibernate, какие конкретные классы использовать. Для этого с помощью интерфейсов, вы должны гнездиться отображение подкласса:

<subclass discriminator-value="SQL" name="ISQLLookupCompanyProperty"> 
    <subclass discriminator-value="SQL" name="SQLLookupCompanyProperty> 
     <property name="TableName" />  
     <property name="KeyField" /> 
     <property name="ValueField" /> 
     <property name="ConnectionString" /> 
    </subclass> 
</subclass> 
<subclass discriminator-value="LIST" name="ILookupCompanyProperty"> 
    <subclass discriminator-value="LIST" name="LookupCompanyProperty" /> 
</subclass> 

Я нашел это решение в blog entry.

+0

В моем случае ISqlLookupCompanyProperty и SqlLookupCompanyProperty находятся в разных сборках - Sample.Data и Sample.Core. Все, о чем я хочу, чтобы nHibernate беспокоился о заполнении интерфейсов, действительно ли нужно знать каждый класс, который реализует эти интерфейсы? –

+0

AFAIK, он должен знать о каждом отображаемом классе. Какой класс вы ожидаете, что он вернется? Он не может вернуть интерфейс, он может возвращать только класс, объявленный как интерфейс. –

+0

Я бы прошел в классах из Sample.Core, которые реализуют интерфейс, объявленный в Sample.Data. Кажется, что невозможно получить истинную трехуровневую систему с nHibernate, вы должны объявить часть своих бизнес-логических объектов в слое данных, или nHibernate не может работать с ними. –

Смежные вопросы