Eu li muitos posts sobre como inserir um DataTable em uma tabela SQL, mas existe uma maneira fácil de puxar uma tabela SQL para um .NET DataTable?
Eu li muitos posts sobre como inserir um DataTable em uma tabela SQL, mas existe uma maneira fácil de puxar uma tabela SQL para um .NET DataTable?
Respostas:
Aqui, experimente isto (este é apenas um 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 deve ser inicializado antes da chamadada.Fill(dataTable)
try/catch
ou o using()
para tratar o erro.
var table = new DataTable();
using (var da = new SqlDataAdapter("SELECT * FROM mytable", "connection string"))
{
da.Fill(table);
}
using
tanto se compreender seu equivalente completo.
Using
?? Isso é como desprezar With
ou Try-Catch
. Eu sou o reverso; Fico desapontado quando não é suportado por uma classe.
De muitas maneiras.
Use ADO.Net e preencha o adaptador de dados para obter uma 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);
}
Você pode então obter a tabela de dados do conjunto de dados.
Nota no conjunto de dados de resposta votada não é usado, (apareceu após minha resposta)
// create data adapter
SqlDataAdapter da = new SqlDataAdapter(cmd);
// this will query your database and return the result to your datatable
da.Fill(dataTable);
O que é preferível ao meu.
Eu recomendaria fortemente olhar para a estrutura de entidade embora ... usar datatables e datasets não é uma boa ideia. Não há segurança de tipo neles, o que significa que a depuração só pode ser feita em tempo de execução. Com coleções fortemente tipadas (que você pode obter usando LINQ2SQL ou estrutura de entidade), sua vida será muito mais fácil.
Edit: Talvez eu não tenha sido claro: Datatables = good, datasets = evil. Se você estiver usando ADO.Net, poderá usar ambas as tecnologias (EF, linq2sql, dapper, nhibernate ou orm of the month), visto que geralmente ficam sobre ado.net. A vantagem que você obtém é que pode atualizar seu modelo com muito mais facilidade à medida que seu esquema muda, desde que você tenha o nível certo de abstração, aproveitando a geração de código.
O adaptador ado.net usa provedores que expõem as informações de tipo do banco de dados, por exemplo, por padrão, ele usa um provedor de servidor sql, você também pode conectar - por exemplo - o provedor de postgress devart e ainda obter acesso às informações de tipo que então permitem que você, conforme descrito acima, use sua orma de escolha (quase sem dor - existem algumas peculiaridades) - acredito que a Microsoft também oferece um provedor oracle. O propósito INTEIRO disso é abstrair da implementação do banco de dados, quando possível.
Versão independente do fornecedor, depende exclusivamente de interfaces ADO.NET; 2 maneiras:
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];
}
}
}
}
Fiz alguns testes de desempenho e a segunda abordagem sempre superou a primeira.
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
parece melhor aos olhos, mas o adaptador de dados tem melhor desempenho (para não confundir que um banco de dados superou o outro, as consultas eram todas diferentes). A diferença entre os dois dependia da consulta. A razão pode ser que Load
várias restrições sejam verificadas linha por linha da documentação ao adicionar linhas (é um método ativado DataTable
) enquanto Fill
está em DataAdapters que foram projetados apenas para isso - criação rápida de DataTables.
DataTable.Load()
com .BeginLoadData()
e .EndLoadData()
atingir a mesma velocidade que com DataSet
.
Modelo centralizado: você pode usá-lo de qualquer lugar!
Você só precisa chamar Below Format de sua função para esta 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);
É isso aí. é um método perfeito.
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;
}
}