using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.IO; using System.Linq; using System.Reflection; using System.Text; namespace Developpez.Dotnet.Data { /// /// Fournit des méthodes d'extension pour la manipulation des datasets /// public static class DataSetExtensions { #region Méthodes d'extension pour IEnumerable /// /// Crée une DataTable à partir d'une séquence d'objets /// /// Le type des éléments de la séquence /// La séquence à partir de laquelle créer une DataTable /// Une DataTable contenant les données de la séquence source /// Les colonnes de la table sont crées à partir des propriétés publiques non-indexées des éléments de la séquence. /// Les propriétés de type référence ou Nullable<T> génèrent des colonnes avec AllowDBNull = true. Les propriétés de type /// valeur génèrent des colonnes avec AllowDBNull = false public static DataTable ToDataTable(this IEnumerable source) { PropertyInfo[] properties = typeof(T).GetProperties() .Where(p => p.CanRead && !p.GetIndexParameters().Any()) .ToArray(); DataTable table = new DataTable(); foreach (var p in properties) { Type type = p.PropertyType; bool allowNull = !type.IsValueType; if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) { allowNull = true; type = Nullable.GetUnderlyingType(type); } DataColumn column = table.Columns.Add(p.Name, type); column.AllowDBNull = allowNull; column.ReadOnly = !p.CanWrite; } foreach (var item in source) { DataRow row = table.NewRow(); foreach (var p in properties) { object value = p.GetValue(item, null) ?? DBNull.Value; row[p.Name] = value; } table.Rows.Add(row); } return table; } #endregion #region Méthodes d'extension pour DataTable #region Sort /// /// Retourne un DataTable trié selon la colonne spécifiée, dans l'ordre croissant /// /// DataTable à trier /// Colonne selon laquelle trier le DataTable /// Retourne un DataTable trié public static DataTable Sort(this DataTable table, DataColumn column) { return Sort(table, column.ColumnName); } /// /// Retourne un DataTable trié selon la colonne et la direction spécifiées /// /// DataTable à trier /// Colonne selon laquelle trier le DataTable /// Direction selon laquelle trier le DataTable /// Retourne un DataTable trié public static DataTable Sort(this DataTable table, DataColumn column, ListSortDirection direction) { return Sort(table, column.ColumnName, direction); } /// /// Retourne un DataTable trié selon la colonne spécifiée, dans l'ordre croissant /// /// DataTable à trier /// Nom de la colonne selon laquelle trier le DataTable /// Retourne un Datatable trié public static DataTable Sort(this DataTable table, string column) { return Sort(table, column, ListSortDirection.Ascending); } /// /// Retourne un DataTable trié selon la colonne et la direction spécifiées /// /// DataTable à trier /// Nom de la colonne selon laquelle trier le DataTable /// Direction selon laquelle trier le DataTable /// Retourne un DataTable trié public static DataTable Sort(this DataTable table, string column, ListSortDirection direction) { table.CheckArgumentNull("table"); column.CheckArgumentNull("column"); string dir = direction == ListSortDirection.Ascending ? "ASC" : "DESC"; DataTable ndt = table.Clone(); int rowCount = table.Rows.Count; DataRow[] rows = table.Select(null, column + " " + dir); for (int i = 0; i < rowCount; i++) ndt.ImportRow(rows[i]); return ndt; } #endregion #region ToCsv /// /// Retourne une string au format CSV dans laquelle sera exporté le DataTable /// /// DataTable à partir duquel effectuer la transformation /// String représentant un DataTable au format CSV public static string ToCsv(this DataTable table) { return ToCsv(table, ",", true); } /// /// Retourne une string au format CSV dans laquelle sera exporté le DataTable /// /// DataTable à partir duquel effectuer la transformation /// Booléen indiquant si les nom des colonnes doivent être inclues dans le CSV généré /// String représentant un DataTable au format CSV public static string ToCsv(this DataTable table, bool includeHeader) { return ToCsv(table, ",", includeHeader); } /// /// Retourne une string au format CSV dans laquelle sera exporté le DataTable /// /// DataTable à partir duquel effectuer la transformation /// Chaîne représentant le délimiteur à utiliser pour la transformation /// String représentant un DataTable au format CSV public static string ToCsv(this DataTable table, string delimiter) { return ToCsv(table, delimiter, true); } /// /// Retourne une string au format CSV dans laquelle sera exporté le DataTable /// /// DataTable à partir duquel effectuer la transformation /// Chaîne représentant le délimiteur à utiliser pour la transformation /// Booléen indiquant si les nom des colonnes doivent être inclues dans le CSV généré /// String représentant un DataTable au format CSV public static string ToCsv(this DataTable table, string delimiter, bool includeHeader) { using (var writer = new StringWriter()) { SaveAsCsv(table, writer, delimiter, includeHeader); return writer.ToString(); } } #endregion #region SaveAsCsv /// /// Crée un fichier CSV dans lequel sera exporté le DataTable /// /// DataTable à partir duquel effectuer la transformation /// Chaîne représentant le délimiteur à utiliser pour la transformation /// Booléen indiquant si les nom des colonnes doivent être inclues dans le CSV généré /// Chemin du fichier dans lequel inscrire le DataTable public static void SaveAsCsv(this DataTable table, string filePath, string delimiter, bool includeHeader) { table.CheckArgumentNull("table"); delimiter.CheckArgumentNull("delimiter"); filePath.CheckArgumentNull("filePath"); using (FileStream fs = File.Open(filePath, FileMode.OpenOrCreate)) { SaveAsCsv(table, fs, delimiter, includeHeader); } } /// /// Crée un fichier CSV dans lequel sera exporté le DataTable /// /// DataTable à partir duquel effectuer la transformation /// Chaîne représentant le délimiteur à utiliser pour la transformation /// Booléen indiquant si les nom des colonnes doivent être inclues dans le CSV généré /// stream dans lequel inscrire le DataTable public static void SaveAsCsv(this DataTable table, Stream stream, string delimiter, bool includeHeader) { table.CheckArgumentNull("table"); delimiter.CheckArgumentNull("delimiter"); stream.CheckArgumentNull("stream"); using (StreamWriter sw = new StreamWriter(stream)) { SaveAsCsv(table, sw, delimiter, includeHeader); } } /// /// Crée un fichier CSV dans lequel sera exporté le DataTable /// /// DataTable à partir duquel effectuer la transformation /// Chaîne représentant le délimiteur à utiliser pour la transformation /// Booléen indiquant si les nom des colonnes doivent être inclues dans le CSV généré /// TextWriter dans lequel inscrire le DataTable public static void SaveAsCsv(this DataTable table, TextWriter textWriter, string delimiter, bool includeHeader) { table.CheckArgumentNull("table"); delimiter.CheckArgumentNull("delimiter"); textWriter.CheckArgumentNull("textWriter"); StringBuilder result; if (includeHeader) { result = new StringBuilder(); foreach (DataColumn column in table.Columns) { result.Append(column.Caption); result.Append(delimiter); } result.Length--; textWriter.WriteLine(result.ToString()); } foreach (DataRow row in table.Rows) { result = new StringBuilder(); foreach (object item in row.ItemArray) { if (item is DBNull || string.IsNullOrEmpty(item.ToString())) result.Append(delimiter); else { string itemAsString = item.ToString(); itemAsString = itemAsString.Replace("\"", "\"\""); result.Append(itemAsString + delimiter); } } result.Length--; textWriter.WriteLine(result.ToString()); } } #endregion #endregion } }