Delphi Three Layer Development tips: TClientDataSet's delta Magical

Source: Internet
Author: User

Delphi to do three layer development, many people will put a tclientdataset on the client, the middle-tier remote data module corresponding to put a tdatasetprovider, and then connected. In fact, this method is very cumbersome, and the procedure carbuncle swollen unwilling, Not good maintenance. We all know that TClientDataSet's Delta property records all modifications to the data, and it allows us to easily implement a common approach to single-table updates.

First, add a method to the middle tier, called Applyupdates. The method is defined as follows:

function applyupdates (const updatetable:string;delta:variant;out err:string): Boolean;

The parameter updatetable refers to the name of the table to be updated, and Delta refers to the Delta property of the TClientDataSet passed over, and if the update error err returns the wrong content. This method is implemented below, first put a query on Datamodule, Query connect to connection, and then put a tdatasetprovider even query. The code is as follows:

function trodm.applyupdates (const updatetable:string;delta:variant;out err:string): Boolean;

Const sql= ' select * from%s where 1<>1 ';

var sqlstr:string;

Errcount:integer;

Begin

Result:=false;

Sqlstr:=format (sql,[updatetable]);

Try

Conn.begintrans;

Query.close;

QUERY.SQL.TEXT:=SQLSTR;

Query.open;

Provider.applyupdates (Delta,-1,errcount);

result:=errcount=0;

If Result Then

Conn.committrans

else Conn.rollbacktrans;

Except

On E:exception do

Begin

Conn.rollbacktrans;

Err:=e.message;

End

End

End

In this case, the general Update method has been completed. However, the client's clientdataset is not yet able to query the display data, so write a query method:

function Querysql (const sqlstr:string;out data:variant;out err:string): Boolean;

Parameter SQLSTR is the query statement to hold the row, data returns the query result, error when err returns error message

The Querysql implementation code is as follows:

function Trodm.querysql (const sqlstr:string;out data:variant;out err:string): Boolean;

Begin

Result:=false;

Try

Query.close;

QUERY.SQL.TEXT:=SQLSTR;

Query.sql.Open;

Data:=provider.data;

Result:=true;

Except

On E:exception do

Err:=e.message;

End

End

Here, the middle layer code is finished, the client's call is simple. For example, the client has a data module DM, put a dcomconnection or socketconnection, named Conn. For example, we are now going to do a product management function, Put a tclientdataset on the form called CDs, put Datasource,dbgrid, etc., set the corresponding properties. Then query back all data when the form was created (create event), with the following code:

Const sql= ' select * from XXXX ';

var data:variant;

err:string;

Begin

If Dm.Conn.AppServer.QuerySQL (Sql,data,err) Then

Cds.data:=data

Else MessageBox (Self.handle,pchar (' Query data error: ' +err '), ' error ', mb_ok+mb_iconerror);

End

Then there are "add", "Modify", "delete" button, the code is the same as we normally do, such as "add" the Code of the button:

Cds.append;

Cds.fieldbyname (' xxx '). asinteger:=xxx;

//....

Cds.post;

Modifications, Delete also writes like this. But now there's a small problem with this table's primary key generation problem, where we can't use the self-increment primary key to generate the primary key ourselves, so you have to write a middle layer in the middle layer to generate the primary key method, the "Increase" button to generate the primary key, and then the above operation. No more talking here .

Additions and deletions after the data is still in the client's memory, want to save to the remote middle-tier server to use the method we just had, the following is the "Save" button under the code:

var err:string;

Begin

If CDs. Changecount=0 then exit;//data is not changed, you don't have to commit.

If Dm.Conn.AppServer.ApplyUpdates (' xxx ', CDs. Delta,err) Then//xxx is the name of the table.

Begin

MessageBox (Self.handle, ' Save succeeded! ', ' hint ', mb_ok+mb_iconinformation);

Cds. mergechangelog;//merging all the changed data

End Else MessageBox (Self.handle,pchar (' Save error: ' +err), ' Error ', mb_ok+mb_iconerror);

End

This article is also finished. With this method, the basic data update of those single tables can also be written as an ancestor class, as long as a virtual method with the name of the update table is added, such as: function tablename:string;virtual; Then its descendants just override this method, return their own table name, the other code is not written.

Delphi Three Layer Development tips: TClientDataSet's delta Magical

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.