Я довольно новичок в Nhibernate, поэтому извиняюсь за длинное описание
Я подозреваю, что изменение структуры устаревшей БД, вероятно, является наилучшим вариантом, но я хочу попробовать и заставить NHibernate справиться с этим.
По сути, структура EndPoint имеет адрес и контакт. Конечная точка хранится в таблице с составным идентификатором (идентификатор адреса, идентификатор контакта).
У меня возникла проблема при каскадном сохранении адреса, который имеет собственный генератор идентификаторов - адреса имеют форму "ADR000234", чтобы соответствовать устаревшей структуре БД.
Генератор пользовательских идентификаторов включает запрос, и когда я сохраняю адрес как часть конечной точки, я получаю переполнение стека. При отладке курсор попадает в строку, которая оценивает запрос (var maxAddressID ..), затем возвращается к началу метода и продолжает это делать, пока не вызовет переполнение стека.
Вот мой класс генератора
public class AddressIdGenerator : IIdentifierGenerator
{
public object Generate(ISessionImplementor session, object obj)
{
var castAsSession = (ISession)session;
var allAddresses = castAsSession.CreateQuery("select max(Code) from Address a");
var maxAddressID = (string)allAddresses.List()[0];
var previousNumber = int.Parse(maxAddressID.Substring(3, 6));
return GetNewId("ADR", previousNumber);
}
private string GetNewId(string prefix, int number)
{
return prefix + (number + 1).ToString().PadLeft(6, '0');
}
}
Вот мое сопоставление с EndPoint CLass
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="DataClasses"
namespace="DataClasses">
<class name="EndPoint" table="[Addresses_Contacts]">
<composite-id>
<key-property name ="Address" column ="[Address ID]" type="string" />
<key-property name ="Contact" column ="[Contact ID]" type="string"/>
</composite-id>
<many-to-one name="Address" class="DataClasses.Address, DataClasses" cascade="save-update"/>
<many-to-one name="Contact" class="DataClasses.Contact, DataClasses" cascade="save-update"/>
</class>
</hibernate-mapping>
и отображение для адреса:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DataClasses" namespace="DataClasses">
<class name="Address" table="[Lookup Addresses]" >
<id name="Code" column="ID" type="string">
<generator class="Nhibernate.AddressIdGenerator, Nhibernate" />
</id>
<property name="OrganisationName" column="[Name of Organisation]"/>
<property name="StreetAddress1" column="[Park/centre/estate]" />
<property name="StreetAddress2" column="[Street Name]" />
<property name="Town" column="[Town/City]" />
<property name="State" column="[Region/ State]" />
<property name="PostCode" column="[Postal/ Area Code]" />
<property name="District" column="[Local District]" />
<property name="Airport" column="[Airport code]" />
<many-to-one name="Country" class="DataClasses.Country, DataClasses" column ="[Country Code]"/>
</class>
</hibernate-mapping>
Если я попытаюсь сохранить и Адресацию самостоятельно, она работает нормально, идентификатор генерируется без проблем.
Также, если я удаляю свойства адреса и контакта из сопоставления (но не из составного идентификатора) и сохраняю адрес и контакт перед сохранением конечной точки, это тоже нормально.
Мне кажется, что когда я делаю каскадное сохранение, по какой-то причине он не может запускать другие запросы во время процесса, но вместо того, чтобы выдавать исключение, он ведет себя странно (перезапускает метод снова и снова). Я никогда не видел, чтобы метод C # делал это раньше. Я хотел бы знать, есть ли у кого-нибудь идея, как это исправить.