Использование nHibernate 3.2, C # 4.0, SQL Server 2008 R2 Express
У меня есть две бизнес-сущности - Broker
и Market
.Они хранятся в таблицах brokers
и markets
соответственно.У меня также есть таблица brokerMarkets
с одним дополнительным столбцом, который называется MinIncrement
.Существует много-много отношений между брокером и рынком, но только тогда, когда я хочу сохранить значение MinIncrement (т.е. это необязательно).Мои классы выглядят так:
public class Market : BusinessBase
{
public Market() {}
public virtual int Id { get; set; }
public virtual string Symbol { get; set; }
public virtual string Description { get; set; }
}
public class Broker : BusinessBase
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual bool IsDefault { get; set; }
public virtual bool IsActive { get; set; }
public virtual ISet<Account> Accounts { get; set; }
}
public class BrokerMarket : Market
{
public BrokerMarket() { }
public virtual Broker Broker {get; set;}
public virtual decimal MinIncrement { get; set; }
}
Мои файлы сопоставления выглядят так: Market.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="MooDB"
namespace="MooDB.BusinessLayer">
<class name="MooDB.BusinessLayer.Market,MooDB" table="markets">
<id name="Id" column="marketId" type="Int32" unsaved-value="0">
<generator class="native" />
</id>
<version name="Version" column="version" type="integer" unsaved-value="0" />
<property name="Symbol" column="symbol" type="String" length="10" not-null="true" />
<property name="Description" column="description" type="String" length="30" not-null="true" />
<set name="Brokers" generic="true" table="brokerMarkets">
<key column="marketId" />
<many-to-many column="brokerId" class="MooDB.BusinessLayer.Broker,MooDB" />
</set>
</class>
</hibernate-mapping>
Broker.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="MooDB"
namespace="MooDB.BusinessLayer">
<class name="MooDB.BusinessLayer.Broker,MooDB" table="brokers">
<id name="Id" column="brokerId" type="Int32" unsaved-value="0">
<generator class="native" />
</id>
<version name="Version" column="version" type="integer" unsaved-value="0" />
<property name="Name" column="broker" type="String" length="50" not-null="true" />
<property name="IsActive" column="isActive" type="bool" not-null="true" />
<property name="IsDefault" column="isDefault" type="bool" not-null="true" />
<set name="Markets" generic="true" table="brokerMarkets">
<key column="brokerId" />
<many-to-many column="marketId" class="MooDB.BusinessLayer.Market,MooDB" />
</set>
<set name="Accounts" table="accounts" generic="true" inverse="true">
<key column="brokerId" />
<one-to-many class="MooDB.BusinessLayer.Account,MooDB" />
</set>
</class>
</hibernate-mapping>
В моем слое доступа к данным у меня есть метод для добавления BrokerMarket:
public void AddBrokerMarket(BrokerMarket bm)
{
using (ITransaction tx = _session.BeginTransaction())
{
try
{
_session.Save(bm);
_session.Flush();
tx.Commit();
}
catch (HibernateException)
{
tx.Rollback();
throw;
}
}
}
В моем модульном тесте я пытаюсь добавить BrokerMarket следующим образом:
[Test]
public void CanAddBrokerMarket()
{
Broker broker = _provider.GetBrokerById(1);
Market market = _provider.GetMarketById(2);
var brokerMarket = new BrokerMarket { Broker = broker, Description = market.Description, Symbol = market.Symbol, MinIncrement = 0.01M };
_provider.AddBrokerMarket(brokerMarket);
}
Когда я запускаю тестЯ получаю эту ошибку:
Запуск тестов.Не удалось выполнить тест «MooDBTests / MooDB / Tests / DataLayerTests / CanAddBrokerMarket»: Сообщение NHibernate.MappingException: нет сохранения для: MooDB.BusinessLayer.BrokerMarket Трассировка стека в NHibernate.Impl.SessionFactoryImpl.GestlImpImpityImpityImpityImpityImpityImpityImpityImpityImpitySP_ImpityImpityImpityImpitySityGerityPity_ImpSignity.Imp_Player(String entityName, Object obj) в NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId (Объектный объект, String entityName, Объект что-нибудь, источник IEventSource, логическое значение requireImmediateIdAccess) в NHibernate.Event.Default.DefaultSaveOventWeventOventEventWeventOventEventLeventOventEventLeventOventEventLeventOventEventLeventOventEventLeventOventEventLeventOventEventLeventOventEventLeventEventLventWvent) СобытиеEvent.Default.DefaultSaveEventListener.SaveWithGeneratedOrRequestedId (SaveOrUpdateEvent событие) в NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient (событие SaveOrUpdateEvent) на NHibernate.Event.Default.DefaultSaveEventListener.PerformSaveOrUpdate (событие SaveOrUpdateEvent) в NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate (событие SaveOrUpdateEvent) в NHibernate.Impl.SessionImpl.FireSave (событие SaveOrUpdateEvent) в NHibernate.Impl.SessionImpl.Save (объектный объект) NHibernateDataProvider.cs (91,0) :BarkDerbBerBDBMDBDBDBDBDBDBDBDBDBDBDBRID_BRID_BRK_D_WR_D_WR_D_D_D_D_D_D_D_D_W_R_P_M_D_D_W_R_P_P_P_M_D_D_P_P_M_D_P_P_P_P_P_P_RUDataLayerTests.cs (81,0): в MooDB.Tests.DataLayerTests.CanAddBrokerMarket ()
Я не уверен, что я сделал неправильно.Нужно ли добавлять коллекцию Broker
в классе Market
и коллекцию Market
в классе Broker
?Я пробовал это, но я получаю ту же ошибку, и я думаю, что где-то что-то концептуально отсутствует.
ОБНОВЛЕНИЕ
Я внес следующие изменения: Рынок.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="MooDB"
namespace="MooDB.BusinessLayer">
<class name="MooDB.BusinessLayer.Market,MooDB" table="markets">
<id name="Id" column="marketId" type="Int32" unsaved-value="0">
<generator class="native" />
</id>
<version name="Version" column="version" type="integer" unsaved-value="0" />
<property name="Symbol" column="symbol" type="String" length="10" not-null="true" />
<property name="Description" column="description" type="String" length="30" not-null="true" />
<map name="BrokerMarkets" table="brokerMarkets" lazy="true" cascade="none">
<cache usage="read-write"/>
<key column="marketId" />
<index column="brokerId" type="Int32" />
<composite-element class="MooDB.BusinessLayer.BrokerMarket,MooDB">
<parent name="Market"/>
<property name="MinIncrement" column="minIncrement" type="decimal" />
<many-to-one name="Broker" class="MooDB.BusinessLayer.Broker,MooDB" column="brokerId" />
</composite-element>
</map>
</class>
</hibernate-mapping>
Broker.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="MooDB"
namespace="MooDB.BusinessLayer">
<class name="MooDB.BusinessLayer.Broker,MooDB" table="brokers">
<id name="Id" column="brokerId" type="Int32" unsaved-value="0">
<generator class="native" />
</id>
<version name="Version" column="version" type="integer" unsaved-value="0" />
<property name="Name" column="broker" type="String" length="50" not-null="true" />
<property name="IsActive" column="isActive" type="bool" not-null="true" />
<property name="IsDefault" column="isDefault" type="bool" not-null="true" />
<set name="Accounts" table="accounts" generic="true" inverse="true">
<key column="brokerId" />
<one-to-many class="MooDB.BusinessLayer.Account,MooDB" />
</set>
</class>
</hibernate-mapping>
Market
класс:
public class Market : BusinessBase
{
public Market() {}
public virtual int Id { get; set; }
public virtual string Symbol { get; set; }
public virtual string Description { get; set; }
public virtual ISet<BrokerMarket> BrokerMarkets { get; set; } //added this line
}
BrokerMarket
класс
public class BrokerMarket : Market
{
public BrokerMarket() { }
public virtual Broker Broker {get; set;}
public virtual Market Market { get; set; } // added this line
public virtual decimal MinIncrement { get; set; }
}
Все остальное без изменений.Я снова запускаю тестовый модуль и получаю:
Запуск тестов.Сбой теста 'MooDBTests / MooDB / Tests / DataLayerTests / CanAddBrokerMarket': Ошибка TestFixtureSetUp в DataLayerTests
Сбой теста 'MooDBTests / MooDB / Tests / DataLayerTests': MooDB.BusinessLayer.Market.BrokerMarkets столбец: brokerId
ОБНОВЛЕНИЕ 2
Если я удаляю
<index column="brokerId" type="Int32" />
из Market.hbm.xml Я получаю эту ошибку при запуске модульного теста:
Запуск тестов.Test 'MooDBTests / MooDB / Тесты / DataLayerTests / CanAddBrokerMarket' не удалось: Сообщение TestFixtureSetUp неудачу в DataLayerTests
1077 * 'MooDBTests / MooDB / Тесты / DataLayerTests' Test Failed: нАлАдкА Сообщение: NHibernate.MappingException: MooDB.Mappings.Market.hbm.xml (17,10): Ошибка проверки XML: элемент 'map' в пространстве имен 'urn: nhibernate-mapping-2.2' имеет недопустимый дочерний элемент 'составной-элемент' в пространстве имен 'urn: nhibernate-mapping-2.2'.Список возможных ожидаемых элементов: 'ключ-карта, составной-ключ-карта,индекс-ключ-многие-ко-многим, индекс, составной-индекс, индекс-многие-ко-многим,
index-many-to-any 'в пространстве имен' urn: nhibernate-mapping-2.2 '. ---->
System.Xml.Schema.XmlSchemaValidationException: элемент 'map' в
пространство имен 'urn: nhibernate-mapping-2.2' имеет недопустимый дочерний элемент
«составной элемент» в пространстве имен «urn: nhibernate-mapping-2.2». Список
ожидаемые возможные элементы: 'ключ-карта, составной-ключ-карта,
индекс-ключ-многие-ко-многим, индекс, составной-индекс, индекс-многие-ко-многим,
index-many-to-any 'в пространстве имен' urn: nhibernate-mapping-2.2 '.