ComponentOne DataObjects for .NET
Keys Assigned by Client: New Row Detached and Attached State
DataObjects for .NET (Enterprise Edition) > Features and Techniques > Adding Rows and Primary Keys > Keys Assigned by Client: New Row Detached and Attached State

This is the simplest case, where a key value is assigned directly by the client application, in essence, by the end user. For example, in the Northwind sample database, the key of the Customers table, CustomerID, is a string abbreviation of the customer name: "ALFKI", "ANTON", and so on, assigned by the user. In this case, there is no "unknown key" problem. However, there is still a problem of transitional state in newly added rows:

Each table row in DataObjects for .NET must have a definite and unique primary key value. A row with an undefined primary key is in a special transitory state called detached. Such a row cannot be used for any purpose except setting its field values. For example, detached rows cannot be used in updating the database. When a new row is added to a table, for example, in a bound grid, or programmatically, with AddNew, it is initially in detached state. To change its state to attached, that is, a fully functional row that can be sent for update, you need to set its primary key field(s) and call the EndEdit method (explicitly or implicitly, see next about AutoEndAddNew).

If setting the primary key is the responsibility of the end user, you do not have to worry about the transition from detached to attached state, DataObjects for .NET does it for you. Its default behavior supports assigning primary key values by the end user. Table views have a special property, AutoEndAddNew. If it is set to True, DataObjects for .NET automatically calls EndEdit when the row's primary key is set for the first time. If the primary key consists of multiple fields, EndEdit will be called when all the key fields receive definite values.

Sometimes, you may need programmatic control over setting primary keys for new rows. For example, you may need to set primary key automatically when a new row is added. This can be done in your business logic code, in the AfterAddNew event, for example:

To write code in Visual Basic

Visual Basic
Copy Code
Private Sub table_Customers_AfterAddNew(ByVal sender As Object, ByVal e As C1.Data.RowChangeEventArgs) Handles TableLogic1.AfterAddNew
    e.DataTable.DataSet.PushExecutionMode _
         (C1.Data.ExecutionModeEnum.Deferred)
    e.Row("CustomerID") = TextBox1.Text
    e.Row.EndEdit()
    e.DataTable.DataSet.PopExecutionMode()
End Sub

To write code in C#

C#
Copy Code
private void table_Customers_AfterAddNew(object sender, C1.Data.RowChangeEventArgs e)
{
    DataTable.DataSet.PushExecutionMode(ExecutionModeEnum.Deferred);
    e.Row["CustomerID"] = textBox1.Text;
    e.Row.EndEdit();
    e.DataTable.DataSet.PopExecutionMode();
}

Execution mode Deferred is used here instead of default mode Immediate, because we need the setting of the primary key and the EndEdit call to execute after all actions related to adding a new row are completed (including notifying bound controls that a row has been added, and so on; it is not safe to perform actions like EndEdit while other actions, such as AddNew have not yet been completed), see Action Order and Execution Mode.