0

После того, как я немного изменил свои сопоставления ( see my other question about cascade-delete for reasons), я попытался вставить совершенно новый объект и все его подклассы.nhibernate mapping не сохраняет/вставляет ключи вставленных подклассов

После этого возникла еще одна проблема с вводом ключей в базу данных. Ситуация такова:

У меня есть объект с 2 уровнями подклассов, как сбор.

Позволяет вызывать объект Родитель, у этого есть коллекция детей, и всякая энтитичность в этой коллекции имеет свою собственную коллекцию enitities. Они отображаются следующим образом. отображение

родителя его <set>

<!--Parent--> 
<set name="Collection" 
    table="Table" 
    cascade="all-delete-orphan" 
    batch-size="15" 
    inverse="true"> 
    <key column="ParentID"/> 
    <one-to-many class="CollectionObject,CollectionObject-ns"/> 
</set 

Mapping CollectionObject в

<id name="ID" column="ID"> 
    <generator class="native"/> 
</id> 

<!-- property mappings--> 
<property name="ParentID" column="ParentID" not-null="true"/> 

<!--collection mapping--> 
<set name="Collection" 
    table="Table" 
    cascade="all-delete-orphan" 
    inverse="true" 
    batch-size="15"> 
    <key column="ChildID"/> 
    <one-to-many class="CollectionObject,CollectionObject-ns"/> 
</set> 

отображения отображение объекта на 2-е коллекции подобно карапузом он выше. Предполагаемый сценарий - сохранение Parent, это приведет к сохранению подклассов/коллекций.

например. У меня есть родитель с ID = 1, Родитель заполнен 1 коллекцией, и эта коллекция имеет 1 собственную коллекцию.

Так что я сохраняю родителя, родитель получает идентификатор из базы данных (собственный идентификатор sql). Теперь первая коллекция должна получить свойство ParentID, заполненное идентификатором, который только что получил из базы данных. И коллекция коллекции должна получить свой ChildID, заполненный идентификатором, который получил ребенок из базы данных, так же, как родитель получил свой ID.

Что происходит сейчас (я проверил созданный SQL в NHProf) Все вставлено со своим идентификатором, но коллекции не получают свой ключевой столбец, заполненный идентификатором своего родительского класса. (вместо этого он просто вставлен 0)

Так что мой вопрос сводится к тому, что я забыл добавить к моему картографированию, которое заставляет это произойти? Не делает ли ключевой столбец то, что я думаю, что он должен делать?

Если я забыл добавить что-нибудь здесь, скажите об этом. Я с удовольствием предоставил дополнительную информацию.

обновление

Я думаю, что проблема, возможно, придется делать с Чайлдс, не имея <many-to-one> тег. Поэтому я попытался добавить один из них к первому отображению дочерних элементов. Я придумал это

<many-to-one name="ParentID" 
      class="Parent,Parent-ns" 
      column="ParentID" 
      not-null="true"/> 

Однако эта установка дает мне следующую ошибку. Exception occurred getter of Parent.ParentID

с InnerException {"Object does not match target type."}

К сожалению, эта ошибка не дает мне какие-либо идеи о том, где продолжить.

ответ

1

Я думаю, было бы полезно, если бы вы могли показать нам свои классы.Проверили ли вы, что ваш класс Parent действительно имеет ParentID свойство типа Parent, и я предполагаю, что вы уже удалили

<property name="ParentID" column="ParentID" not-null="true"/> 

от вашего отображения и заменить его на многие-к-одному? Наконец, если вы хотите, чтобы ваш ребенок возражает иметь коллекции дочерних объектов, то дочерний объект также будет нуждаться многие-к-одному

<many-to-one name="CollectionObjectParent" 
      class="CollectionObject,CollectionObject-ns" 
      column="ChildID" 
      not-null="true"/> 
+0

Эй Gareth, Я не уверен, если я понимаю вас полностью. Родитель должен иметь свойство ParentID собственного типа? как Parent ParentID {get; set;} В настоящее время ParentID - это целое число, которое запутано сейчас :) – marn

+0

Вместо добавления ссылки на DocumentID вам нужно ссылаться на фактический родительский объект Document. См. Ссылку на информацию о том, как справляться с родительскими ситуациями ребенка - надеюсь, что это поможет http://www.nhforge.org/doc/nh/en/index.html#example-parentchild – Gareth

+0

Я прочитал документацию, близкую к 20x но я все еще скучаю по чему-то. Я опубликовал обходной путь ниже, и он должен сделать на данный момент, но все же открыт для предложений. В настоящее время я смотрю сеансы http://www.summerofnhibernate.com/. в надежде, что он станет немного более понятным для меня. – marn

0

К сожалению, после того, как играть с отображениями и чтение корыта половину интернета, у меня нет смог решить это.

Проблема заключается в том, что я не могу получить к сценарию, который <Document> получает свой ключ из базы данных <generator class="native"/> и после этого вставит ключ в ForeignKey свойств его основных классов, внутри только один session.Save() вызова.

например. для сценария я хотел бы session.Save(document)

- * новый документ обнаружен - * получить новую идентичность

- * документ имеет подкласс с ForeignKey к нему!
- * вставить idenity в указанный ForeignKey свойства (угадайте здесь лежит проблема)

и повторить это со всеми, лежащих в основе классов.

Я все же придумал обходное решение (самый уродливый код из когда-либо, но он выполняет свою работу). Я действительно не разделяю код, этот дерьмовый, но он просто может помочь людям, читающим здесь.

Я еще не отказался от решения этого правильного пути, но на данный момент это нужно сделать. Стань открытой для подталкивания в лучшем направлении.

входящий код дерьма!

public void InsertDocument(Document document) 
    { 
     using (ISession session = NHibernateHelper.OpenSession()) 
     { 
      using (ITransaction transaction = session.BeginTransaction()) 
      { 
       try 
       {           
        IDocument document2 = new Document(); 
        document2.Bodyregels = document.Bodyregels; 
        //for making the query a little neater 
        document.Bodyregels = null;       

        //lets get the elusive identity 
        session.Save(document); 
        session.Flush(); 

        //reattach subclass and enter the id explicitly 
        document.Bodyregels = document2.Bodyregels; 
        foreach (DocumentBodyregel dbr in document.Bodyregels) 
        { 
         dbr.DocumentID = document.DocumentID; 
        } 

        //save it again, now with filled FK 
        session.Save(document); 
        session.Flush(); 

        //now save the final subclass with FK's 
        foreach (DocumentBodyregel dbr in document.Bodyregels) 
        { 
         foreach (DocumentBodyregelWaarde dbrw in dbr.Waardes) 
         { 
          dbrw.RegelID = dbr.ID; 
          dbrw.DocumentID = document.DocumentID; 
         } 
        } 

        //and save the entire thing again (now with FK's) 
        session.Save(document); 
        transaction.Commit(); 
       } 
       catch (Exception e) 
       { 
        transaction.Rollback(); 
        throw e; 
       } 
      } 
     } 
    }