0

My model contains the following entities:

  <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>

I have the following code:

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

I get an error when adding the entity to the collection, because the Id property contains the value 0. How can I solve this? I do not want to save the entity before adding it to the collection.

Willem
  • 111
  • 4
  • There is no other way, as the .NET/BOM layer must know an entity key before it can be linked to another entity. With identity keys, you must go back to the database (Save) at least once to determine what will be the key. Otherwise, choose guid as entity key type. – Simon Mourier Jan 10 '16 at 08:29

1 Answers1

1

You have to tell CodeFluent that it must use a list instead of a dictionary for the orderlines by means of the setType attribute. After that CodeFluent will no longer use the Id property for the Add and Contains methods, but still checks for the value 0 in the Add method, so you also have to add an OnAfterCreate rule that initializes the Id property:

  <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>

Now the code works. The orderlines are added and saved within the transaction that is created when saving the order. After saving the order, the orderlines have got their id values from the database:

  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();
Bas Klerx
  • 11
  • 2