【发布时间】:2011-08-29 17:24:16
【问题描述】:
我已经阅读了很多关于将 DataTable 插入 SQL 表的帖子,但是有没有一种简单的方法可以将 SQL 表拉入 .NET DataTable 中?
【问题讨论】:
-
嗯...在 DataAdapter 上使用 Fill 方法?
标签: c# .net asp.net sql datatable
我已经阅读了很多关于将 DataTable 插入 SQL 表的帖子,但是有没有一种简单的方法可以将 SQL 表拉入 .NET DataTable 中?
【问题讨论】:
标签: c# .net asp.net sql 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();
}
}
【讨论】:
datatable字段必须在调用da.Fill(dataTable)之前初始化
try/catch或using()来处理错误。
var table = new DataTable();
using (var da = new SqlDataAdapter("SELECT * FROM mytable", "connection string"))
{
da.Fill(table);
}
【讨论】:
using 的等价物,您可能不会那么鄙视它。
Using??这就像鄙视With或Try-Catch。我是相反的;当一个类不支持它时,我很失望。
方法很多。
使用 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);
}
然后您可以从数据集中获取数据表。
未使用赞成的答案数据集中的注释,(它出现在我的答案之后) 会的
// create data adapter
SqlDataAdapter da = new SqlDataAdapter(cmd);
// this will query your database and return the result to your datatable
da.Fill(dataTable);
哪个比我的更可取。
我强烈建议您查看实体框架……但使用数据表和数据集并不是一个好主意。它们没有类型安全性,这意味着只能在运行时进行调试。使用强类型集合(可以通过使用 LINQ2SQL 或实体框架获得),您的生活会轻松很多。
编辑:也许我不清楚:数据表 = 好,数据集 = 邪恶。如果您使用的是 ADO.Net,那么您可以同时使用这两种技术(EF、linq2sql、dapper、nhibernate 和 orm of the month),因为它们通常位于 ado.net 之上。您获得的优势是,只要您通过利用代码生成具有正确的抽象级别,就可以在架构更改时更轻松地更新模型。
ado.net 适配器使用暴露数据库类型信息的提供程序,例如默认情况下它使用 sql server 提供程序,您也可以插入 - 例如 - devart postgress 提供程序并仍然可以访问类型信息然后,这将允许您如上所述使用您选择的 orm(几乎无痛 - 有一些怪癖) - 我相信微软也提供了一个 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];
}
}
}
}
我做了一些性能测试,第二种方法总是优于第一种。
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 看起来更好,但数据适配器性能更好(不要混淆一个数据库优于另一个,查询都是不同的)。两者之间的差异取决于查询。原因可能是Load 需要在添加行时逐行检查各种约束from the documentation(它是DataTable 上的一种方法),而Fill 位于专门为此而设计的DataAdapters 上——快速创建DataTables .
【讨论】:
.BeginLoadData() 和.EndLoadData() 包围DataTable.Load() 以达到与DataSet 相同的速度。
中心化模型:您可以在任何地方使用它!
你只需要从你的函数调用下面的格式到这个类
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;
}
}
【讨论】: