Midas Raiders

xiaoxiao2021-03-06  47

It took a long time with Midas, I saw some Midas source code, a little experience, let's write a MIDAS system that develops a request response mode.

System structure

Client's clientDataSet directly connects to the Server's Provider, which can constitute the easiest MIDAS system, but the disadvantage of this system is obvious.

1. Need to register the AppServer on the client, even if you find that you can write a registry, solve this problem, still adding the complexity of deployment.

2. Data transmitted within the system will be completely masked. You basically can't do any adjustments for large systems, you update a data, maybe Roundtrip ran several rounds, and request response will be Roundtrip,

3.ClientDataSet and Provider connection, you have two solutions, A, a business, a CP pair (ClientDataSet, Provider), trouble, and there is stateful .b. Use only one CP pair, change clientDataSet.comMandtext To return to different data, this is not a pool of appserver, the performance is serious,

So the recommended model is

The Client side uses clientDataSet to make a local cache table, the interface of the interface is provided by the clientDataSet, and the data of the clientDataSet is only called WebService, and the COM component is also a way to get data. When the user is updated, the local transfer clientDataSet Delta gives the backend and updates.

Server end uses clientDataSet-> proviker-> DataSet to get data, return to the clientDataSet Data to the caller, then release or close, become a stateful AppServer, update, send the DEALTA to the caller, pay to ClientDataSet and do Update, then release or close immediately.

Realization of Server

GetData application is very simple, there is no special, when it is Updatedata, take an example as an example, we get Table1 data, return to the client, the client can perform CREATE, UPDATE, DELETE , Then submit a change in one time, (sigh, Midas Delta is really good, I always think this is perfect),

We look at how Server should write code when Updatedata, the key

1.Provider's resolvetodataset is TRUE or False

2.Provider's UpdateMode

3. Settings of Tfield's Providerflags

The resolvetodataset makes it easy to generate the SQL statement when you call clientDataSet.ApplyUpdates, or generated by AdoQuery,

If you are True, you will be generated by AdoQuery. At the beginning, my setting is adoQuery.sql is not set, anything, but set the 'SELECT * from Table1 where 1 = 0' in ClientDataSet.commandtext, here 1 = 0 is not required to open the clientDataSet, which will actually perform the CREATE operation, generate the correct INSERT statement .update and delete operations will report "Unable to find record. No key specified" error, The reason is because use AdoQuery to do updates, but at this time, use where 1 = 0, there is no data in AdoQuery, and AdoQuery update (ie, DataSet updates) is based on existing data to generate SQL statements, and there is this error. Of course, a solution is where 1 = 1, so, sweat, you will not write such a code, or analyze delta to only make updates, but write code is too tired, so set it to False,

Set to false No problem? When set to false, there is clientDataSet to do updates. Even if WHERE 1 = 0 can generate the correct CUD SQL statement, but look at the updatemode settings, what effect will be produced,

Ipwhereall

In this way, when building a SQL statement, the WHERE field 1 = value 1 and field 2 = value 2 ..... and field n = value N is queried statement to do a single record update, of course, this way is no problem, but If there is a DateTime type field and this field is not null, you will not find any records, (I found this error on SQL Server 2000, maybe there is no problem on other databases), you need to discover 2.UPwherechanged

When you update COL1 and COL2, generate "where col1 = original value 1 and col2 = original value 2", see the problem? If you have the two fields in this table, there are many records of these two fields, then What is terrible. Of course, a field is the case, see what is helpful

upWhereAll All columns (fields) are used to locate the record.upWhereChanged Only key field values ​​and the original value of fields that have changed are used to find the record.upWhereKeyOnly Only key fields are used to find the record.

He can include the key field, what is the key field? ], If we set the primary key of the table (he is unique) to Keyfield, then the above where statement will be "where primarykey = primary key field and col1 = original value 1 and col2 = original value 2", then data positioning There will be no problem, my test results completely explain this problem, so I will pass multiple parameters in updating, that is, the primary key name of the table to update, but the problem is still not resolved, its SQL statement does not "Primarykey" = Main key field ", so I confused, starting to see the source code of the Providers unit, finally discovered the problem, I set the FieldDataSet Field, and the provider is a reference to the TDataSet, which is set. Field, that is, AdoQuery, then I fix this error and see the correct WHERE clause is submitted to the database, cool ..

WITH FPROVIDER.DATASET.FIELDBYNAME (PKFIELD) Do Providerflags: = Providerflags [PFINKEY];

3.UPwhereKeyonly

Look at this, Only Key Fields Are Used to Find The Record, if you set the primary key of the table to Keyfield, what else do you want to do? I set up the provider's updatemode to this, when updated, WHERE clause Is "where primarykey = primary key field", huh, it is quite good, tested, success,

Here is my UPDATE function.

procedure TBaseDatabase.UpdateData (const pkField, theSql, theDelta: string); procedure SetDateTimeFieldProviderFlags (theField: TField); begin if theField.DataType in [ftDate, ftTime, ftDateTime] then theField.ProviderFlags: = theField.ProviderFlags - [pfInWhere]; End; begin with fcds do beg, fprovider.dataset.close; // Turn adoQuery close; commandText: = theseql; open; xmldata: = theDelta; // Client transferred updates, is Midas Delta Packet // ShowMessageEx (INTOSTR (FPROVIDER.DATASET.FIELDCOUNT); // Date type field is the main reason why it cannot locate records, set its ProvIerFlags set // foreachfieldindataset (fcds, @SetDateTimefieldProviderflags); doDataSetopen; // Open AdoQuery to get Fields information // Set it The primary key field is Keyfield with fProvider.DataSet.fieldbyname (pkfield) do providerflags: = provoderflags [pfinkey]; applyupdates (0); end; end; where Delta can include any multiple times of the client, such as CREATE two records Update a record, delete 5 records.

This is a single-table operation, or it can extend the operation of the master from the table, one-time transmission of the master slave table, for example, can be defined

Procedure TBaseDatabase.UpdatedAns (Const Pkfield: String; consthet, these); arraystring;

I like to write the Server end into COM to execute, then add a layer of WebService in COM and Client to get remote support. Welcome everyone to pay more valuable.

These issues have been solved for a day.

转载请注明原文地址:https://www.9cbs.com/read-54846.html

New Post(0)