将SQL表读入C#DataTable

我已经阅读了很多有关将DataTable插入到SQL表中的文章,但是有没有简单的方法将SQL表拖入.NET DataTable?

在这里,给这个镜头(这只是一个伪代码)

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(); } } 
 var table = new DataTable(); using (var da = new SqlDataAdapter("SELECT * FROM mytable", "connection string")) { da.Fill(table); } 

很多方法。

使用ADO.Net并使用数据适配器上的填充来获取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); } 

然后您可以从数据集中获取数据表。

注意在upvoted答案数据集没有使用,(它出现在我的答案)它的确如此

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

哪个更适合我的。

我强烈build议查看entity framework,尽pipe…使用数据表和数据集不是一个好主意。 它们没有types安全性,这意味着debugging只能在运行时完成。 对于强types集合(您可以从使用LINQ2SQL或entity framework获得),您的生活将变得更加简单。

编辑:也许我不清楚:Datatables =好,数据集=邪恶。 如果您使用的是ADO.Net,那么您可以使用这两种技术(EF,linq2sql,dapper,nhibernate,orm),因为它们通常位于ado.net之上。 你得到的好处是你可以更容易地更新你的模型,因为你的模式变化提供了正确的抽象级别。

ado.net适配器使用暴露数据库types信息的提供者,例如默认情况下它使用sql服务器提供者,也可以插入 – 例如devart postgress提供者,并且仍然可以访问types信息让你像上面一样使用你的select(几乎是无痛的 – 有一些怪癖) – 我相信微软也提供了一个oracle提供商。 这样做的总体目的是在可能的情况下从数据库实现中抽象出来。

供应商独立版本,完全依靠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]; } } } } 

我做了一些性能testing,第二种方法总是跑赢第一。

 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看起来更好看,但数据适配器performance更好(不要混淆一个数据库胜过另一个,查询都是不同的)。 两者之间的区别取决于查询。 原因可能是Load需要在添加行(它是DataTable上的一个方法)时逐行检查各种约束,而Fill则在DataAdapters上,而DataAdapters是为此而devise的 – 快速创buildDataTable。