DABindingList

Data Abstract for .NET provides a LINQ query provider for Data Abstract services that works with .NET 3.5 Framework and later, and RemObjects Oxygene and allows you to write type-safe query expressions with strongly typed code.

There are two samples which cover the the use of DA LINQ. This sample which covers using the DABindingList class, which is a generic collection class that supports data binding and is useful for using with user interface elements like tables, and using a DA LINQ query to retrieve rows from a table in schema as well as alternative methods for inserting, updating and deleting rows.

The other sample DALINQ more generally covers using DA LINQ and the LinqRemoteDataAdapter class.

Getting Started

The sample is typically located in C:\Program Files (x86)\RemObjects Software\Data Abstract for .NET\Samples\<language>\DABindingList, though you may have installed the Data Abstract for .NET SDK and it's samples in another location.

To build it, you will of course need Visual Studio, and like all the samples provided with Data Abstract for .NET you will need to be running Relativity Server with the DASamples Domain and the Simple Schema available.

Running the Sample

When run the sample displays a window that is split into two parts, the first is a toolbar that contains a combo box that contains the server address, and five buttons. The "Load" button will retrieve the table data freshly from the server specified in the combo box and use a DA LINQ to select all of the rows available in the table.

The "Add" button creates a new Client object that represents a row in the table and opens a dialog that allows you to edit the details of the new record. In this sample the fields of the dialog are pre-populated. The "Edit" button opens an edit dialog and populates it with the contents of the selected row. The "Delete" button will delete the currently selected row, and finally the "Apply" button will apply the local changes to the server.

Examining the Code

The sample is comprised of 5 classes, though the sections below focus largely on the DataModule class. It is this class that handles the interaction with the Data Abstract server, creates the DA LINQ query, retrieves an instance of DABindingList and has the methods to add, update and delete a row from the Clients table.

The Clients and Simple_TableDefinitions classes were generated by the Table Definition Classes wizard provided by Data Abstract for .NET; the classes handle representing the Clients table in the Simple schema and individual clients.

The ClientsForm class handles the dialog for editing the details of a Clients row. The MainForm class handles the main user interface, and interacts with the DataModule to work with the data.

Using LinqRemoteDataAdapter

Rather than using the RemoteDataAdapter that other samples use, this sample uses the LinqRemoteDataAdapter class. It, like the RemoteDataAdapter, is a Data Adapter that handles the communication between the client program and the server. Configuring the connection and handling login is identical between the classes, though how they interact with the schema and tables is different. Note that the LinqRemoteDataAdapter adapter does not support Dynamic Where or Dynamic Select per se, but you can use DA LINQ to achieve the same results.

The LinqRemoteDataAdapter also handles tracking the changes to the table data (for instance adding a new row, or deleting an existing one) until the ApplyChanges method is called. At this point all local changes will be applied to the server.

Getting an instance of DABindingList

The DABindingList class, available in the RemObjects.DataAbstract.Linq assembly, is a generic collection class that supports data binding and is perfect for acting as a data source for a DataGrid or other user interface control.

In this particular sample the DABindingList class is used to represent the Clients table in the Simple schema in the client program, and is assigned as the data source for an instance of System.Windows.Forms.BindingSource in MainForm, which is in turn assigned as the data source for the DataGridView used to display the table data.

To get an instance of DABindingList we first use a LINQ query to select the data we require from the server which returns an instance of BindingList. Data Abstract for .NET provides an extension class (BindingListExtensions) which provides the helper method ToDABindingList which will create an instance of DABindingList from the data in the previously retrieved BindingList.

The SelectClients method is called from MainForm when the user clicks on the "Load" button.

 

public void SelectClients()
{
    var clientsQuery = from c in linqRemoteDataAdapter.GetTable<Clients>() select c;
    this.Clients = clientsQuery.ToDABindingList();
}

 

method DataModule.SelectClients;
begin
  var clientsQuery :=  from c in linqRemoteDataAdapter.GetTable<Clients>() select c;
  self.Clients := clientsQuery.ToDABindingList()
end;

 

public func SelectClients() {

  var clientsQuery = linqRemoteDataAdapter.GetTable<Clients>().Select({x in x});
    self.Clients = clientsQuery.ToDABindingList()
}

 

Public Sub SelectClients()
    Dim clientsQuery = From c In linqRemoteDataAdapter.GetTable(Of Clients)() Select c
    Me.Clients = BindingListExtensions.ToDABindingList(Of Clients)(clientsQuery)
End Sub

Adding a row to the table

Adding a new row to the table is different than was demonstrated in the DALINQ sample, which shows you adding the new row directly to the LinqRemoteDataAdapter using its InsertRow method.

When using a DABindingList the new Clients object that represents a new client is added directly to the DABindingList using its Add method.

 

public void AddClient(Clients client)
{
   this.Clients.Add(client);
}

 

method DataModule.AddClient(client: Clients);
begin
  self.Clients.Add(client)
end;

 

public func AddClient(client: Clients!) {

    self.Clients.Add(client)
}

 

Public Sub AddClient(client As Clients)
    Me.Clients.Add(client)
End Sub

Updating a row

Updating an existing row is as simple as updating the properties of the data object representing the row (handled here by the ClientForm class) and then calling the EndUpdate method of the Clients class. This method is defined in the Simple_TableDefinitions file.

The EndUpdate method takes an instance of the LinqRemoteDataAdapter class and calls its UpdateRow method to replace the old values with the new data.

The LinqRemoteDataAdapter data adapter will track all of the changes to the data which will be applied to the server when the ApplyChanges method is called.

 

public void UpdateClient(Clients client)
{
    client.EndUpdate(linqRemoteDataAdapter);
}

 

method DataModule.UpdateClient(client: Clients);
begin
  client.EndUpdate(linqRemoteDataAdapter)
end;

 

public func UpdateClient(client: Clients!) {

    client.EndUpdate(linqRemoteDataAdapter)
}

 

Public Sub UpdateClient(client As Clients)
    client.EndUpdate(linqRemoteDataAdapter)
End Sub

Removing a row

To delete an existing row it needs to be removed from the DABindingList, this is achieved by passing the object we wish to delete to the Remove method of DABindingList.

 

public void DeleteClient(Clients client)
{
    this.Clients.Remove(client);
}

 

method DataModule.DeleteClient(client: Clients);
begin
  self.Clients.Remove(client)
end;

 

public func DeleteClient(client: Clients!) {

    self.Clients.Remove(client)
}

 

Public Sub DeleteClient(client As Clients)
    Me.Clients.Remove(client)
End Sub