I e-conomic API, är dataklasser ett kraftfullt sätt att optimera hämtning, upprättande eller uppdatering av flera attribut – eller till och med flera poster – med användning av så få anrop som möjligt.

Många utvecklare störs dock av det faktum att när man använder dataklasser, returneras bara enkla egenskaper – alltså att det krävs ytterligare anrop för att hämta egenskaper tillhörande refererade objekt.

Anta att vi till exempel vill lista artikelnummer, artikelnamn och artikelgruppsnummer för alla våra artiklar. Följande verkar vara det självklara sättet att uppnå detta:

IProduct [] arrP = session.Product.GetAll ();
IProductData [] arrPD = session.ProductData.GetDataArray (arrP);
foreach (IProductData PD arrPD)
{
Console.WriteLine (”Antal:” + pd.Number.ToString ());
Console.WriteLine (”Namn:” + pd.Name)
Console.WriteLine (”Grupp:” + pd.ProductGroup.Number.ToString ());
Console.WriteLine (””);
}

Detta bör leda till endast två anrop – en för Product.GetAll() och en för ProductData.GetDataArray () – eller hur?

Fel!

För varje artikel kommer ovanstående kod även generera ett anrop för att hämta artikelgruppsnumret (i praktiken ett anrop till SOAP-funktion ProductGroup_GetNumber ). Slutresultatet är ett antal anrop motsvarande n +2, där n betecknar antalet artiklar. Detta verkar väldigt onödigt – speciellt eftersom antalet artiklar oftast är flera tiopotenser högre än antalet artikelgrupper.

Först av allt – varför är dataklasserna utformade på detta sätt? Varför returnerar IProductData klassen objektreferenser till IProductGroup istället för IProductGroupData objekt?

Även om det verkar vara mer i linje med tanken bakom dataklasser, fundera på konsekvenserna av om alla dataobjekt skulle inkludera refererade objekt som andra dataobjekt. I ovanstående exempel:

•  IProductData skulle inkludera IProductGroupData
•  som skulle inkludera IAccountData
•  vilket skulle kunna inkludera IVatAccountData ( IAccount.VatAccount kan vara null)
•  som skulle innehålla IAccountData
•  och så vidare

Med andra ord kan detta snabbt leda till massiv ”rekursiv” hämtning av data som man i de flesta fall inte skulle ha någon användning för.
Lyckligtvis finns det ett annat sätt att minska antalet anrop till ett absolut minimum: Hämta alla artikelgrupper på en gång, och lagra dem i ett ”dictionary” med IProductGroup som nyckel:

IProductGroup [] arrPG = session.ProductGroup.GetAll ();
IProductGroupData [] arrPGD = session.ProductGroupData.GetDataArray (arrPG);
Dictionary<IProductGroup, IProductGroupData> PGD = new Dictionary <IProductGroup, IProductGroupData> ();
for (int x = 0, x <arrPG.Length; x + +)
{
PGD [arrPG [x]] = arrPGD [x];
}
IProduct [] arrP = session.Product.GetAll ();
IProductData [] arrPD = session.ProductData.GetDataArray (arrP);
foreach (IProductData PD arrPD)
{
Console.WriteLine (”Antal:” + pd.Number.ToString ());
Console.WriteLine (”Namn:” + pd.Name)
Console.WriteLine (”Grupp:” + PGD . [pd.ProductGroup]. Number.ToString ());
Console.WriteLine (””);
}

Detta genererar bara fyra anrop oberoende av antal artiklar eller artikelgrupper. Liknande trick kan förstås användas med alla dataklasser som innehåller objektreferenser.

En sista, och delvis relaterat prestandatips: Resultatet av GetAll() mot en GetDataArray() kan naturligtvis fortfarande leda till att stora mängder data hämtas. Som en allmän regel rekommenderar vi att du delar upp GetAll() resultatet till grupper á 500 poster för efterföljande datahämtning. Även om detta givetvis kommer att leda till något fler anrop, blir risken för timeout betydligt mindre i vardera ände.

Ta en titt på vår API-dokumentation  – eller för den delen – läs gärna Christians originaltext.