Vous consultez une page technique concernant le logiciel de gestion Mercator. Celle-ci contient des informations spécifiques destinées aux professionnels de Mercator. Souhaitez-vous être redirigés vers des informations plus générales ?


   Ne plus poser cette question

Utilisation de l'extension RowsEnumerable typée sur DataTable

0000003102     -      08/08/2022

Mercator dispose de la méthode Api.Zselect typée pour obtenir directement le résultat d'une extraction dans la base de données SQL sous la forme d'une liste d'objets. Cette méthode ne permet toutefois que d'obtenir un seul jeu de données (l'équivalent d'une seule DataTable). Si on souhaite, obtenir plusieurs jeux de données typés, alors il faut utiliser cette extension de MercatorExtensions :

Zoom
public static IEnumerable<T> RowsEnumerable<T>(this DataTable dt, Func<DataRow, bool> predicate = null)

 

Soit le script SQL suivant, contenant deux requêtes, donc produisant deux DataTables :

select c_id,c_nom,c_cat1,sum(tot_bas_fb) as tot_ca from CLI left join PIEDS_V on cli.c_id=pieds_v.id_cli where ... group by c_id,c_nom,c_cat1
select f_id,f_nom,f_cat2,sum(tot_bas_fb) as tot_ca from FOU left join PIEDS_A on fou.f_id=pieds_a.id_fou where ... group by f_id,f_nom,f_cat2

 

Nous créons ces deux classes afin de typer les résultats obtenus :

Zoom
public class CliAndCa
{
    public string c_id { get; set; }
    public string c_nom { get; set; }
    public string c_cat1 { get; set; }
    public double? tot_ca { get; set; }
}

public class FouAndCa
{
    public string f_id { get; set; }
    public string f_nom { get; set; }
    public string f_cat2 { get; set; }
    public double? tot_ca { get; set; }
}

 

Notez que dans ces deux classes, tot_ca est un double nullable (double?), puisque la jointure left join peut produire une valeur null pour cette colonne.

Le code élémentaire pour produire deux listes typées selon ces classes est alors le suivant :

Zoom
string reqSql = "select c_id,c_nom,c_cat1,sum(tot_bas_fb) as tot_ca from CLI left join PIEDS_V on cli.c_id=pieds_v.id_cli where ... group by c_id,c_nom,c_cat1 \r\n"
              + "select f_id,f_nom,f_cat2,sum(tot_bas_fb) as tot_ca from FOU left join PIEDS_A on fou.f_id=pieds_a.id_fou where ... group by f_id,f_nom,f_cat2";
DataSet ds = Api.Zselect(MercatorController.Globals.RepData, reqSql);
if (ds != null)
{
    List<CliAndCa> listCliAndCa = ds.Tables[0].RowsEnumerable<CliAndCa>().ToList();
    List<FouAndCa> listFouAndCa = ds.Tables[1].RowsEnumerable<FouAndCa>(dr => dr["f_id"].ToString().StartsWith("A")).ToList();
}

 

Pour l'élaboration de la liste des fournisseurs, nous passons en plus en paramètre un prédicat qui permet de ne prendre en compte que les fournisseurs dont le F_ID commence par "A". Ce prédicat effectue un filtrage sur les DataRows de la DataTable.

Les principes de conception des classes sont identiques à ceux qui prévalent pour la méthode Api.Zselect typée.

Contrairement à la méthode Api.Zselect typée, il y a ici un dédoublement de données : l'information existe d'une part dans le DataSet et d'autre part dans les listes créées par l'extension. Il n'y a pas de liaison entre les deux. (Donc, une modification dans la List<T> n'entraîne aucune modification dans le DataSet, et vice versa).

La raison d'être de cette extension est d'alléger les notations en permettant de ne plus devoir répéter à l'infini des System.ConvertTo... sur des éléments de DataRows.