Добавление несохраненного объекта в коллекцию в отношении композиции дает ошибку при использовании persistenceIdentity.

Моя модель содержит следующие сущности:

  <cf:entity name="Order" cfom:bindingList="false">
    <!--persistenceIdentity is true, because the corresponding column for this property must be auto incremented by the database.-->
    <cf:property name="Id" typeName="ulong" key="true" persistenceIdentity="true" cfps:hint="CLUSTERED" />

    <!-- composition relation -->
    <cf:property name="Orderlines" typeName="{0}.OrderlineCollection" cascadeDelete="Before" cascadeSave="After" />

    <cf:method name="Save">
      <cf:rule typeName="transaction" transactionType="TransactionScope" timeout="00:60:00" scopeOption="Required" />
    </cf:method>
  </cf:entity>

  <cf:entity name="Orderline" cfom:bindingList="false">

    <!--persistenceIdentity is true, because the corresponding column for this property must be auto incremented by the database.-->
    <cf:property name="Id" typeName="ulong" key="true" persistenceIdentity="true" cfps:hint="CLUSTERED" />

    <!-- Relation back to indicate an 1-to-n composition relationship. -->
    <cf:property name="Order" typeName="{0}.Order" />
  </cf:entity>

У меня есть следующий код:

  Order order = new Order();
  Orderline orderline = new Orderline();
  order.Orderlines.Add(orderline);  // ERROR
  order.Save();  // Save the order and its orderlines

Я получаю сообщение об ошибке при добавлении объекта в коллекцию, потому что свойство Id содержит значение 0. Как я могу решить эту проблему? Я не хочу сохранять объект перед добавлением его в коллекцию.


person Willem    schedule 09.01.2016    source источник
comment
Другого пути нет, поскольку уровень .NET/BOM должен знать ключ объекта, прежде чем его можно будет связать с другим объектом. С идентификационными ключами вы должны вернуться к базе данных (Сохранить) по крайней мере один раз, чтобы определить, какой будет ключ. В противном случае выберите guid в качестве типа ключа сущности.   -  person Simon Mourier    schedule 10.01.2016


Ответы (1)


Вы должны указать CodeFluent, что он должен использовать список вместо словаря для строк заказа с помощью атрибута setType. После этого CodeFluent больше не будет использовать свойство Id для методов Add и Contains, но по-прежнему будет проверять значение 0 в методе Add, поэтому вам также необходимо добавить правило OnAfterCreate, которое инициализирует свойство Id:

  <cf:entity name="Orderline" cfom:bindingList="false" setType="List">

    <!--persistenceIdentity is true, because the corresponding column for this property must be auto incremented by the database.-->
    <cf:property name="Id" typeName="ulong" key="true" persistenceIdentity="true" cfps:hint="CLUSTERED" />

    <cf:property name="Name" typeName="string" />

    <!-- Relation back to indicate an 1-to-n composition relationship. -->
    <cf:property name="Order" typeName="{0}.Order" />

    <cf:rule typeName="OnAfterCreate" />
    <cf:snippet name="OnAfterCreate" language="CSharp">
      <!-- here or in a partial class -->
      private void OnAfterCreate()
      {
      this._id = long.MaxValue;
      }
    </cf:snippet>
  </cf:entity>

Теперь код работает. Строки заказов добавляются и сохраняются в транзакции, которая создается при сохранении заказа. После сохранения заказа строки заказов получили значения идентификаторов из базы данных:

  Order order = new Order();

  Orderline orderline = new Orderline();
  orderline.Name = "First order";
  order.Orderlines.Add(orderline);

  orderline = new Orderline();
  orderline.Name = "second order";
  order.Orderlines.Add(orderline);

  order.Save();
person Bas Klerx    schedule 13.01.2016