An api call in Uniconta is always associated with an overhead. First the api must establish a connection to the server, then encrypt and send the network package. On the server side the server will receive the package. Decrypt the package and branch out in the server and then to the method. At that point the Uniconta server will do its job. The result of the job will then be streamed, zipped and encrypted. The Windows server will then return the package to the api, that will close the connection, decrypt the package and return the result to the call.
As you see, there is a tremendous overhead of making an api call. That is why we have developed several technics to minimize the round trip to the server.
Caching
Caching of master data is one of the best ways to minimize network traffic. You load master data once and store it in a cache and then use the cache to make lookup of master data.
In the Uniconta api, we have built in classes to cache and load master data. The Uniconta windows client uses these classes to keep master data. If you write a plugin, you can take advances of, that most master data is already loaded and you can use the save cache objects as the Uniconta client is using.
This has several advantages both for your plugin but also for the Uniconta client. When you use the same cache object as the Uniconta client, any modification to data, will be seen both by your plugin and the Windows client, since they share the same cache. Secondly, loading data will only be done once or on demand by the user, when he wants a fresh reload of data.
The normal syntax for loading data is like this:
var Debtors = await api.Query<DebtorClient>();
To use cache instead, you just write:
var Debtors = await api.LoadCache<DebtorClient>();
This class you get from LoadCache has the interface IEnumable<DebtorClient>, which mean that you can do a foreach on Debtors.
In case you want to loop over the debtors you just do this:
foreach(var rec in Debtors) { // do something }
in case you want a subset of debtors, it still much better to use LoadCache. After a call to LoadCache you can do this:
var subset = (from rec in Debtors where rec.ZipCode == “1000” && rec.Country == CountryCode.Denmark select rec).ToList();
if you want to lookup debtors from a reference value, there is a “Get()” method.
var Debtor = Debtors.Get(“1000”) // value passed is account number var Debtor = Debtors.Get(1234) // value passed is rowed.
Let’s suppose you want to loop over some inventory transactions and for each transaction you want to look up the debtor or the creditor, that is marked on the inventory transaction to get some values.
var Debtors = await api.LoadCache < Debtor > (); var Creditors = await api.LoadCache < Creditor > (); var trans = await api.Query < InvTrans > (); foreach(var tran in trans) { if (tran._DCAccount != null) { if (tran._MovementType == (byte) InvMovementType.Debtor) { var rec = Debtors.Get(tran._DCAccount); } else if (tran._MovementType == (byte) InvMovementType.Creditor) { var rec = Creditors.Get(tran._DCAccount); } } }
Insert, Update and Delete records.
We have api methods to insert, update and delete records.
These methods have several profiles. We have methods that takes one record and we have methods that takes a list of records.
If you want to insert several records, you can insert these records in a list and then call insert on the list. This way you can insert thousand of records in one call.
Please note, that if you want to insert hundred and thousand of records, you should not insert them in one call, you should break it down to calls, that insert a list of 1000 records at the time.
In Uniconta windows client, we have Tools/Import. Here a user can import records into the screen, evaluate that the values are correct and then press “save”. Internally in the Uniconta client, what we do is that we insert a list of records for every 100 line. This way we can show the user an activity and at the same time break down the number of calls. Inserting 100 records takes a little less that 1 second, so it gives a nice and fast user interface with a completion bar from 0-100% that updates every second and insert 100 records at the time. We just the same principle in our import program, that can import from C5, E-conomic and NAV. We insert 100 records at the time and show a nice progress bar.
What we recommend is to save 100 records at a time, but again, it is up to you what is easiest for you.
Same way we insert a list of 100 records in one api call, you can also delete and update a list of records in one call.
List<>, Dictionary<> and Array[] in C#
C# is a very powerful and fast language. You should use C# to do all the things you can do.
Sorting: inserted of calling api.Query() and pass a sorting, it is much faster to just load the data unsorted and then ask C# to sort it. When you have a list, dictionary or array, to call a sorter takes one line of code.
Query: we see many times that programmers break down a query in a lot of small queries. This is not efficient. Instead you should call query and get all data on one call, then you can use C# to break down the result into several lists or dictionaries. This is again much faster and mush more efficient.