web-dev-qa-db-fra.com

Lire la table SQL dans C # DataTable

J'ai lu de nombreux articles sur l'insertion d'un DataTable dans une table SQL, mais existe-t-il un moyen simple d'extraire une table SQL dans un .NET DataTable?

72
Will

Ici, essayez ceci (ceci est juste un pseudocode)

using System;
using System.Data;
using System.Data.SqlClient;


public class PullDataTest
{
    // your data table
    private DataTable dataTable = new DataTable();

    public PullDataTest()
    {
    }

    // your method to pull data from database to datatable   
    public void PullData()
    {
        string connString = @"your connection string here";
        string query = "select * from table";

        SqlConnection conn = new SqlConnection(connString);        
        SqlCommand cmd = new SqlCommand(query, conn);
        conn.Open();

        // create data adapter
        SqlDataAdapter da = new SqlDataAdapter(cmd);
        // this will query your database and return the result to your datatable
        da.Fill(dataTable);
        conn.Close();
        da.Dispose();
    }
}
122
yonan2236
var table = new DataTable();    
using (var da = new SqlDataAdapter("SELECT * FROM mytable", "connection string"))
{      
    da.Fill(table);
}
61
Tim Rogers

Beaucoup de façons.

Utilisez ADO.Net et utilisez fill sur l'adaptateur de données pour obtenir un DataTable:

using (SqlDataAdapter dataAdapter
    = new SqlDataAdapter ("SELECT blah FROM blahblah ", sqlConn))
{
    // create the DataSet 
    DataSet dataSet = new DataSet(); 
    // fill the DataSet using our DataAdapter 
    dataAdapter.Fill (dataSet);
}

Vous pouvez ensuite extraire la table de données de l'ensemble de données. 

La note dans le jeu de données de réponse upvoted n’est pas utilisée (elle est apparue après ma réponse)

// create data adapter
SqlDataAdapter da = new SqlDataAdapter(cmd);
// this will query your database and return the result to your datatable
da.Fill(dataTable);

Ce qui est préférable au mien.

Cependant, je vous recommande fortement de regarder le cadre des entités ... utiliser des tables de données et des ensembles de données n'est pas une bonne idée. Il n'y a pas de sécurité de type sur eux, ce qui signifie que le débogage ne peut être effectué qu'au moment de l'exécution. Avec des collections fortement typées (que vous pouvez obtenir en utilisant LINQ2SQL ou un framework d'entités), votre vie sera beaucoup plus facile.

Edit: Peut-être que je n'étais pas clair: Datatables = bon, datasets = evil. Si vous utilisez ADO.Net, vous pouvez utiliser ces deux technologies (EF, linq2sql, dapper, nhibernate ou mois), car elles reposent généralement sur ado.net. L'avantage que vous obtenez est que vous pouvez mettre à jour votre modèle beaucoup plus facilement à mesure que votre schéma change, à condition que vous disposiez du niveau d'abstraction approprié en optimisant la génération de code.

L’adaptateur ado.net utilise des fournisseurs qui exposent les informations de type de la base de données. Par exemple, il utilise par défaut un fournisseur de serveur SQL, vous pouvez également vous connecter, par exemple, au fournisseur devart postgress tout en ayant accès aux informations de type. vous permettent, comme indiqué ci-dessus, d’utiliser votre orme de choix (presque sans douleur - il ya quelques problèmes) - je pense que Microsoft fournit également un fournisseur Oracle. Le but COMPLET de ceci est d’abstraire autant que possible l’implémentation de la base de données.

11
John Nicholas

Version indépendante du fournisseur, repose uniquement sur les interfaces ADO.NET; 2 façons:

public DataTable Read1<T>(string query) where T : IDbConnection, new()
{
    using (var conn = new T())
    {
        using (var cmd = conn.CreateCommand())
        {
            cmd.CommandText = query;
            cmd.Connection.ConnectionString = _connectionString;
            cmd.Connection.Open();
            var table = new DataTable();
            table.Load(cmd.ExecuteReader());
            return table;
        }
    }
}

public DataTable Read2<S, T>(string query) where S : IDbConnection, new() 
                                           where T : IDbDataAdapter, IDisposable, new()
{
    using (var conn = new S())
    {
        using (var da = new T())
        {
            using (da.SelectCommand = conn.CreateCommand())
            {
                da.SelectCommand.CommandText = query;
                da.SelectCommand.Connection.ConnectionString = _connectionString;
                DataSet ds = new DataSet(); //conn is opened by dataadapter
                da.Fill(ds);
                return ds.Tables[0];
            }
        }
    }
}

J'ai fait des tests de performance et la seconde approche a toujours surperformée la première.

Stopwatch sw = Stopwatch.StartNew();
DataTable dt = null;
for (int i = 0; i < 100; i++)
{
    dt = Read1<MySqlConnection>(query); // ~9800ms
    dt = Read2<MySqlConnection, MySqlDataAdapter>(query); // ~2300ms

    dt = Read1<SQLiteConnection>(query); // ~4000ms
    dt = Read2<SQLiteConnection, SQLiteDataAdapter>(query); // ~2000ms

    dt = Read1<SqlCeConnection>(query); // ~5700ms
    dt = Read2<SqlCeConnection, SqlCeDataAdapter>(query); // ~5700ms

    dt = Read1<SqlConnection>(query); // ~850ms
    dt = Read2<SqlConnection, SqlDataAdapter>(query); // ~600ms

    dt = Read1<VistaDBConnection>(query); // ~3900ms
    dt = Read2<VistaDBConnection, VistaDBDataAdapter>(query); // ~3700ms
}
sw.Stop();
MessageBox.Show(sw.Elapsed.TotalMilliseconds.ToString());

Read1 semble mieux sur les yeux, mais l'adaptateur de données fonctionne mieux (pour ne pas confondre une base de données plus performante que l'autre, les requêtes étaient toutes différentes). La différence entre les deux dépendait de la requête. La raison pourrait en être que Load requiert la vérification de plusieurs contraintes ligne par ligne dans la documentation lors de l’ajout de lignes (sa méthode est sur DataTable), alors que Fill est sur des DataAdapters conçus uniquement pour cela - création rapide de DataTables.

7
nawfal

Modèle centralisé: vous pouvez l'utiliser n'importe où!

Il vous suffit d'appeler ci-dessous Format de votre fonction à cette classe

DataSet ds = new DataSet();
SqlParameter[] p = new SqlParameter[1];
string Query = "Describe Query Information/either sp, text or TableDirect";
DbConnectionHelper dbh = new DbConnectionHelper ();
ds = dbh. DBConnection("Here you use your Table Name", p , string Query, CommandType.StoredProcedure);

C'est tout. c'est une méthode parfaite. 

public class DbConnectionHelper {
   public DataSet DBConnection(string TableName, SqlParameter[] p, string Query, CommandType cmdText) {
    string connString = @ "your connection string here";
    //Object Declaration
    DataSet ds = new DataSet();
    SqlConnection con = new SqlConnection();
    SqlCommand cmd = new SqlCommand();
    SqlDataAdapter sda = new SqlDataAdapter();
    try {
     //Get Connection string and Make Connection
     con.ConnectionString = connString; //Get the Connection String
     if (con.State == ConnectionState.Closed) {
      con.Open(); //Connection Open
     }
     if (cmdText == CommandType.StoredProcedure) //Type : Stored Procedure
     {
      cmd.CommandType = CommandType.StoredProcedure;
      cmd.CommandText = Query;
      if (p.Length > 0) // If Any parameter is there means, we need to add.
      {
       for (int i = 0; i < p.Length; i++) {
        cmd.Parameters.Add(p[i]);
       }
      }
     }
     if (cmdText == CommandType.Text) // Type : Text
     {
      cmd.CommandType = CommandType.Text;
      cmd.CommandText = Query;
     }
     if (cmdText == CommandType.TableDirect) //Type: Table Direct
     {
      cmd.CommandType = CommandType.Text;
      cmd.CommandText = Query;
     }
     cmd.Connection = con; //Get Connection in Command
     sda.SelectCommand = cmd; // Select Command From Command to SqlDataAdaptor
     sda.Fill(ds, TableName); // Execute Query and Get Result into DataSet
     con.Close(); //Connection Close
    } catch (Exception ex) {

     throw ex; //Here you need to handle Exception
    }
    return ds;
   }
  }
0
Elango S