SQLテーブルをC#DataTableに読み込みます


回答:


156

ここで、これを試してみてください(これは単なる擬似コードです)

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();
    }
}

18
datatableフィールドは、呼び出す前に初期化する必要がありますda.Fill(dataTable)
Dabblernl

@ yonan2236datatableの横にtsqlからの出力パラメータがあるのはどうですか?出力パラメータも取得する方法は?出来ますか?サンプル?
アフマッドエブラヒミ2015

1
このコードはエラーが発生しやすいため、利用可能なリソースをこのように使用することはお勧めしません。クリーンなソリューションについては、@ TimRogersの回答を参照してください。
Xan-Kun Clark-Davis

それとは別に、LINQを見てください(まだ行っていない場合)。ここで実際に魔法をかけることができます:-)
Xan-KunClark-

78
var table = new DataTable();    
using (var da = new SqlDataAdapter("SELECT * FROM mytable", "connection string"))
{      
    da.Fill(table);
}

7
@ Xan-KunClark-Davis:例外がスローされると、受け入れられた回答のコードがリソースをリークします。using完全に同等のものを理解していれば、それほど軽蔑しないかもしれません。
Ben Voigt 2017年

@ Xan-KunClark-Davisなぜあなたは軽蔑するのですUsingか?それは軽蔑WithやのようなものTry-Catchです。私は逆です。クラスでサポートされていないのでがっかりしました。
SteveCinq

12

たくさんの方法。

ADO.Netを使用し、データアダプターでfillを使用して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);
}

次に、データセットからデータテーブルを取得できます。

賛成の回答データセットのメモは使用されていません(私の回答の後に表示されました)使用されています

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

これは私のものよりも好ましいです。

ただし、エンティティフレームワークを確認することを強くお勧めします...データテーブルとデータセットを使用することはお勧めできません。それらには型安全性はありません。つまり、デバッグは実行時にのみ実行できます。強く型付けされたコレクション(LINQ2SQLまたはエンティティフレームワークを使用して取得できる)を使用すると、作業がはるかに簡単になります。

編集:おそらく私は明確ではありませんでした:Datatables =良い、データセット=悪い。ADO.Netを使用している場合は、これらのテクノロジ(EF、linq2sql、dapper、nhibernate、今月のorm)の両方を使用できます。これらは、通常、ado.netの上にあります。あなたが得る利点は、コード生成を活用することによって適切なレベルの抽象化があれば、スキーマが変更されるときにモデルをはるかに簡単に更新できることです。

ado.netアダプターは、データベースのタイプ情報を公開するプロバイダーを使用します。たとえば、デフォルトではSQLサーバープロバイダーを使用します。また、devart postgressプロバイダーをプラグインしても、タイプ情報にアクセスできます。上記のように、選択したormを使用できるようにします(ほとんど痛みを伴わずに-いくつかの癖があります)-MicrosoftもOracleプロバイダーを提供していると思います。これの全体的な目的は、可能な場合はデータベースの実装から抽象化することです。


1
型付きデータセットには、EFと同様に、型安全性と強い型付きコレクションがあります。ただし、これらは、アプリがデータベースに緊密に結合されている場合にのみ使用されます。多くの異なるデータベースで動作する必要のあるツールを作成している場合、型安全性は絶望的な願いです。
ロスプレッサー2014年

1
.netに入力されたデータセットは、xmlの狂気と悲惨さの恐ろしい創造物です。私は、マイクロソフトが入力したデータセットのすべてを維持するオーバーヘッドを喜んで受け入れる場所で働いたことがありません。最近、マイクロソフトでさえその賢明な提案をしているとは思いません。もちろん、複数のデータベースでの型安全性については、それを取得できます。重要なのは、型付きコレクションにできるだけ早く変換して渡し、型の問題を特定の場所に制限することです。Ormsはそれを支援し、複数のデータベースで完全に機能します。EFが気に入らない場合は、dapperのような軽いものを使用してください。
ジョンニコラス

1
あなたは私を理解していませんでした。接続するデータベースの種類がわからない汎用ツールを作成している場合、型安全性は絶望的な願いです。
ロスプレッサー2014年

1
SQLが与えられます。また、データベースの種類がわからない場合、なぜデータベースである必要があるのでしょうか。そのような一般的なツールのアプリケーションは何でしょうか?本当に根本的に異なるデータベースに接続する必要がある場合は、リポジトリパターンの背後で抽象化して、その内部にさまざまな専用データベースアダプターが必要になり、その時点で詳細を知ることができます。事実は、コードを消費することは、アダプターでタイプの期待->タイプのアサーションを持っているということです。制約があるということは、データベース言語がわからないため、クエリを実行できないことを意味します。
ジョンニコラス

3
SSMSクローンを作成しているとしましょう。
ロスプレッサー2014年

9

ベンダーに依存しないバージョンで、ADO.NETインターフェイスのみに依存しています。2つの方法:

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

私はいくつかのパフォーマンステストを行いましたが、2番目のアプローチは常に最初のアプローチを上回りました。

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見た目は良くなりますが、データアダプターのパフォーマンスは向上します(一方のデータベースが他方のデータベースよりも優れていることを混同しないでください。クエリはすべて異なっていました)。ただし、この2つの違いはクエリによって異なります。その理由は、そのためだけに設計されたDataAdapters(DataTablesの高速作成)で行を追加するときに、ドキュメントからLoad行ごとにさまざまな制約をチェックする必要があるためである可能性があります。DataTableFill


3
あなたは囲む必要があるDataTable.Load().BeginLoadData()して.EndLoadData()と同じ速度を達成するためにDataSet
ニコラボグダノビッチ

1

中心化モデル:どこからでも使用できます!

関数からこのクラスにBelowFormatを呼び出す必要があります

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);

それでおしまい。それは完璧な方法です。

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;
   }
  }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.