U bevindt zich nu op een technische pagina over de software Mercator. Deze pagina bevat specifieke informatie die bestemd is voor professionals van de software Mercator. Wenst u naar algemenere informatie over Mercator door te gaan?


   Deze vraag niet meer stellen

Gebruik van getypeerde Api.Zselect-methoden

0000002752     -      04-01-2025

Mercator heeft altijd een complete set Api.Zselect() methoden aangeboden voor het verkrijgen van gegevens uit de SQL database in de vorm van een DataSet. Het is nu ook mogelijk om dezelfde methoden te gebruiken in een getypeerde versie, Api.Select<T>(), om direct een List<T> te verkrijgen. Het voordeel hiervan is dat het resultaat van elke kolom getypeerd zal zijn, waardoor het vermijden van conversies mogelijk is, en men kan genieten van het gemak van intellisense en de veiligheid die de typecontrole van de compiler biedt.

Om een getypeerde Zselect methode te gebruiken, moet je een objectklasse definiëren die overeenkomt met de gegevens die zullen worden geëxtraheerd door de SQL query. Kolomnamen moeten overeenkomen met de namen van eigenschappen in de klasse (case non sensitive).

In het volgende voorbeeld willen we een lijst van klanten verkrijgen, met deze informatie :

  • De klant ID
  • Hun naam
  • Hun regime
  • Voor hun laatste verkoop :
    • De datum
    • Het type verkoop (1 = factuur, 2 = levering, ...)
    • De referentie.

Als de klant nog nooit een verkoop heeft gedaan, willen we dat de laatste 3 waarden null zijn.

De eerste stap is het definiëren van een klasse die overeenkomt met de structuur van de informatie die zal worden opgehaald uit de database. :

Zoom
public class CLI_LAST_SALE
{
    public string C_ID { get; set; }
    public string C_NOM { get; set; }
    public Int16 C_REGIME { get; set; }
    public DateTime? DATE { get; set; }
    public Int16? TYPE { get; set; }
    public string REFERENCE { get; set; }
}

 

Vervolgens is de code die het resultaat zal produceren eenvoudig als volgt :

Zoom
string reqSql = @"
    select * into #pvtmp from (
        select id,journal,piece,id_cli,date,reference,type,ROW_NUMBER() OVER (PARTITION BY p2.id_cli ORDER BY p2.date desc,p2.type desc) as rn from pieds_v p2
        ) t
    where rn=1

    select c.C_ID,c.C_NOM,c.C_REGIME,p.DATE,p.TYPE,p.REFERENCE from CLI c
        left join #pvtmp p on (c.c_id=p.id_cli)

    drop table #pvtmp";

List<CLI_LAST_SALE> l = Api.Zselect<CLI_LAST_SALE>(MercatorUi.Globals.RepData, reqSql);

 

Als de gegevens niet kunnen worden opgehaald (SQL-fout) of als de mapping naar de klasse die als type is doorgegeven niet kan worden uitgevoerd, dan is het resultaat van Zselect<T>() null. Dit geval moet altijd worden getest.

Bij het ontwerpen van de klasse moet je rekening houden met het volgende :

  • De naam van de eigenschappen moet strikt gelijk zijn aan de naam van de kolom die wordt geretourneerd door de SQL-query. Deze vergelijking is niet hoofdlettergevoelig.
  • De mapping tussen SQL-types en .net-types moet strikt worden gerespecteerd. (zie hieronder: Sinds versie 11.0.302...)
    • bigint = Int64
    • binary = Byte[]
    • bit = Boolean
    • char = String
    • date = DateTime
    • datetime = DateTime
    • decimal = Decimal
    • float = Double
    • image = Byte[]
    • int = Int32
    • nchar = String
    • numeric = Decimal
    • nvarchar = String
    • smallint = Int16
    • tinyint = Byte
    • uniqueidentifier = Guid
    • varbinary = Byte[]
    • varchar = String
  • Bij het kiezen van types moet je bepalen of de eigenschap waarschijnlijk null-waarden zal bevatten of niet. Dit het geval als de SQL-kolom toestaat dat null-waarden worden opgeslagen of bijvoorbeeld tijdens een join (left of right), wanneer er geen corresponderend record wordt gevonden. Bepaalde types, zoals String, Byte[] kunnen altijd een null-waarde opslaan. In dit geval is er niets speciaals nodig. In het geval van "waarde" types, moet je aangeven dat het type nullable is door er een ? aan toe te voegen. Bijvoorbeeld Int16?, DateTime?, ... In het bovenstaande voorbeeld is REGIME niet nullable omdat het zeker is dat daar geen null-waarde moet worden opgeslagen, terwijl TYPE dat wel moet zijn (in het geval dat er geen verkoop is gedaan voor deze klant).
  • De klasse en alle eigenschappen die moeten worden geassocieerd met resultaten moeten openbaar zijn.
  • In de klasse moeten eigenschappen { get; set; } worden gebruikt; geen eenvoudige velden.
  • De klasse kan andere eigenschappen, velden of methoden bevatten. Deze worden genegeerd. Als de klasse een constructor bevat, moet deze een constructor bevatten die geen parameters vereist.
  • De SQL query kan extra kolommen teruggeven aan de publieke eigenschappen van de mapping klasse. Deze worden gewoon genegeerd.
  • De SQL query moet een enkele dataset teruggeven. (Voor meervoudig getypeerde DataTables, zie deze pagina(zie hieronder: Sinds versie 11.0.303...)

Eigenschappen van het type String worden automatisch rechts getrimd wanneer ze worden toegewezen.

 

Net als bij de ongetypeerde versie is er een hele reeks handtekeningen beschikbaar :

Zoom
public static List<T> Zselect<T>(SqlConnection conn, SqlCommand cmd, MercatorSqlParam[] pp, SqlTransaction transaction, bool withSchema);
public static List<T> Zselect<T>(SqlConnection conn, SqlCommand cmd, MercatorSqlParam[] pp, SqlTransaction Transaction);
public static List<T> Zselect<T>(SqlConnection conn, SqlCommand cmd, MercatorSqlParam[] pp);
public static List<T> Zselect<T>(SqlConnection conn, SqlCommand cmd, List<MercatorSqlParam> listPp, SqlTransaction transaction);
public static List<T> Zselect<T>(SqlConnection conn, SqlCommand cmd, List<MercatorSqlParam> listPp);
public static List<T> Zselect<T>(SqlConnection conn, SqlCommand cmd, MercatorSqlParam p1 = null, MercatorSqlParam p2 = null, MercatorSqlParam p3 = null, MercatorSqlParam p4 = null, MercatorSqlParam p5 = null, MercatorSqlParam p6 = null, MercatorSqlParam p7 = null, MercatorSqlParam p8 = null, MercatorSqlParam p9 = null);
public static List<T> Zselect<T>(MercatorSqlConnection conn, string reqSql, List<MercatorSqlParam> listPp);
public static List<T> Zselect<T>(MercatorSqlConnection conn, string reqSql, MercatorSqlParam[] pp);
public static List<T> Zselect<T>(MercatorSqlConnection conn, string reqSql, MercatorSqlParam p1 = null, MercatorSqlParam p2 = null, MercatorSqlParam p3 = null, MercatorSqlParam p4 = null, MercatorSqlParam p5 = null, MercatorSqlParam p6 = null, MercatorSqlParam p7 = null, MercatorSqlParam p8 = null, MercatorSqlParam p9 = null);
public static List<T> Zselect<T>(string repData, string reqSql, MercatorSqlParam[] pp, bool withSchema);
public static List<T> Zselect<T>(string repData, string reqSql, MercatorSqlParam[] pp);
public static List<T> Zselect<T>(string repData, string reqSql, List<MercatorSqlParam> listPp, bool withSchema);
public static List<T> Zselect<T>(string repData, string reqSql, List<MercatorSqlParam> listPp);
public static List<T> Zselect<T>(string repData, string reqSql, MercatorSqlParam p1 = null, MercatorSqlParam p2 = null, MercatorSqlParam p3 = null, MercatorSqlParam p4 = null, MercatorSqlParam p5 = null, MercatorSqlParam p6 = null, MercatorSqlParam p7 = null, MercatorSqlParam p8 = null, MercatorSqlParam p9 = null);
public static List<T> Zselect<T>(string repData, SqlCommand Comm);

 

Deze methode bestaat ook in een asynchrone versie: ZselectAsync.

Vergeet niet dat het mogelijk is om de code van een mapping klasse direct in een customizer te plaatsen. Dit kan bijvoorbeeld voor de tweede (afsluitend) accolade onderaan de code. Dit levert een klasse op die genest is in de customizer klasse en die gebruikt kan worden door Api.Zselect<T>().

Voorbeeld : Afbeeldingen laden in de SQL-database


Sinds versie 11.0.301 van MercatorTunnel is het mogelijk om een Tuple als type voor de lijst te gebruiken. Hierdoor is het niet meer nodig om een klasse te maken.

Zoom
List<(string c_id, string c_nom, Int16 c_tarif, bool c_sommeil, string c_codep, string c_ville, string c_num_tva)> l = Api.Zselect<(string c_id, string c_nom, Int16 c_tarif, bool c_sommeil, string c_codep, string c_ville, string c_num_tva)>(Globals.RepData, "select c_id,c_nom,c_tarif,c_sommeil,c_codep,c_ville,c_num_tva from CLI where ...");

Door de interne implementatie van Tuples mag het aantal elementen in de tuple maximaal 7 zijn. De volgorde van de elementen in de Tuple moet overeenkomen met de volgorde van de kolommen die door de SQL-query worden geretourneerd. Er wordt geen rekening gehouden met de namen van de elementen in de Tuples (omdat dit een notatie is die alleen door de compiler bekend is).

Het is ook mogelijk om een basistype uit de bovenstaande lijst door te geven. Dit is ideaal voor query's die slechts één kolom ophalen.

Zoom
List<string> l = Api.Zselect<string>(Globals.RepData, "select c_id from CLI where ...");

Sinds versie 11.0.302 van MercatorTunnel is de nauwkeurigheid van numerieke typen versoepeld. Mercator voert de typewijziging automatisch uit wanneer dat nodig en mogelijk is.

Bijvoorbeeld: PIEDS_V.PIECE is van het type NUMERIC(11,0) in de database. Standaard komt dit SQL-type overeen met het type Decimal van .net., maar het is mogelijk om in plaats daarvan het type Int64 te gebruiken.


Sinds versie 11.0.303 van MercatorTunnel is het mogelijk om een SQL-query te gebruiken die 2 of 3 datasets extraheert. Om dit te doen, moet u deze handtekeningen gebruiken:

  • Zselect<T1T2>
  • Zselect<T1T2T3>

Hieronder vindt u een voorbeeldcode:

Zoom
public class PiedDescriptor
{
    public Int64 piece { get; set; }
    public string journal { get; set; }
}

...

string reqSql = "select top 10 piece,journal from PIEDS_V \r\n"
              + "select c_id,c_nom,c_tarif,c_sommeil from CLI where c_tarif<>0 or c_condit<>0 \r\n"
              + "select top 10 piece from pieds_a order by piece desc";

var r = Api.Zselect<PiedDescriptor, (string c_id, string c_nom, Int16 c_tarif, bool c_sommeil), Int64>(Globals.RepData, reqSql);
if (r != null)
{
    List<PiedDescriptor> listPieds = r.List0;
    List<(string c_id, string c_nom, Int16 c_tarif, bool c_sommeil)> listCli = r.List1;
    List<Int64> listPieces = r.List2;
}