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
}
}