He leído muchas publicaciones sobre cómo insertar un DataTable en una tabla SQL, pero ¿hay una manera fácil de extraer una tabla SQL en un .NET DataTable?
He leído muchas publicaciones sobre cómo insertar un DataTable en una tabla SQL, pero ¿hay una manera fácil de extraer una tabla SQL en un .NET DataTable?
Respuestas:
Aquí, dale una oportunidad (esto es solo un pseudocódigo)
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
campo debe inicializarse antes de llamarda.Fill(dataTable)
var table = new DataTable();
using (var da = new SqlDataAdapter("SELECT * FROM mytable", "connection string"))
{
da.Fill(table);
}
using
tanto si comprende su equivalente completo.
Using
?? Eso es como despreciar With
o Try-Catch
. Yo soy al revés; Estoy decepcionado cuando no es apoyado por una clase.
De muchas formas.
Use ADO.Net y use fill en el adaptador de datos para obtener 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);
}
Luego puede sacar la tabla de datos del conjunto de datos.
Tenga en cuenta que en el conjunto de datos de respuesta votada a favor no se usa (apareció después de mi respuesta)
// create data adapter
SqlDataAdapter da = new SqlDataAdapter(cmd);
// this will query your database and return the result to your datatable
da.Fill(dataTable);
Que es preferible al mío.
Sin embargo, recomendaría encarecidamente mirar el marco de la entidad ... usar tablas de datos y conjuntos de datos no es una gran idea. No hay seguridad de tipo en ellos, lo que significa que la depuración solo se puede realizar en tiempo de ejecución. Con colecciones fuertemente tipadas (que puede obtener usando LINQ2SQL o el marco de la entidad) su vida será mucho más fácil.
Editar: Quizás no estaba claro: tablas de datos = bueno, conjuntos de datos = malvado. Si está utilizando ADO.Net, puede utilizar ambas tecnologías (EF, linq2sql, dapper, nhibernate, orm of the month), ya que generalmente se encuentran en la parte superior de ado.net. La ventaja que obtiene es que puede actualizar su modelo mucho más fácilmente a medida que cambia su esquema, siempre que tenga el nivel correcto de abstracción mediante la generación de código.
El adaptador ado.net utiliza proveedores que exponen la información de tipo de la base de datos, por ejemplo, de forma predeterminada, utiliza un proveedor de servidor SQL, también puede conectar, por ejemplo, el proveedor de postgress devart y seguir teniendo acceso a la información de tipo que luego le permite utilizar el formato de su elección como se indicó anteriormente (casi sin dolor, hay algunas peculiaridades); creo que Microsoft también proporciona un proveedor de Oracle. El propósito COMPLETO de esto es abstraerse de la implementación de la base de datos cuando sea posible.
Versión independiente del proveedor, se basa únicamente en interfaces ADO.NET; 2 maneras:
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];
}
}
}
}
Hice algunas pruebas de rendimiento y el segundo enfoque siempre superó al primero.
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
se ve mejor a los ojos, pero el adaptador de datos funciona mejor (no confundir que un db superó al otro, las consultas fueron todas diferentes). Sin embargo, la diferencia entre los dos dependía de la consulta. La razón podría ser que Load
requiere que se verifiquen varias restricciones fila por fila de la documentación al agregar filas (es un método activado DataTable
) mientras Fill
está en DataAdapters que fueron diseñados solo para eso: creación rápida de DataTables.
DataTable.Load()
con .BeginLoadData()
y .EndLoadData()
para lograr la misma velocidad que con el DataSet
.
Modelo centrado: ¡puedes usarlo desde cualquier lugar!
Solo necesita llamar al formato de abajo desde su función a esta clase
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);
Eso es. es un método perfecto.
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;
}
}