Przeczytałem wiele postów na temat wstawiania DataTable do tabeli SQL, ale czy istnieje łatwy sposób na ściągnięcie tabeli SQL do .NET DataTable?
Przeczytałem wiele postów na temat wstawiania DataTable do tabeli SQL, ale czy istnieje łatwy sposób na ściągnięcie tabeli SQL do .NET DataTable?
Odpowiedzi:
Tutaj, daj temu szansę (to tylko pseudokod)
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
Pole musi zostać zainicjowane przed wywołaniemda.Fill(dataTable)
var table = new DataTable();
using (var da = new SqlDataAdapter("SELECT * FROM mytable", "connection string"))
{
da.Fill(table);
}
using
tak bardzo, jeśli rozumiesz jego pełny odpowiednik.
Using
?? To jak pogardzanie With
lub Try-Catch
. Ja jestem odwrotnie; Jestem rozczarowany, gdy nie jest obsługiwany przez klasę.
Wiele sposobów.
Użyj ADO.Net i użyj wypełnienia adaptera danych, aby uzyskać 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);
}
Następnie możesz pobrać tabelę danych ze zbioru danych.
Uwaga w zbiorze danych dotyczących odpowiedzi za pozytywnymi odpowiedziami nie jest używany (pojawiło się po mojej odpowiedzi)
// create data adapter
SqlDataAdapter da = new SqlDataAdapter(cmd);
// this will query your database and return the result to your datatable
da.Fill(dataTable);
Co jest lepsze od mojego.
Zdecydowanie zalecałbym jednak przyjrzenie się strukturze encji ... używanie danych i zestawów danych nie jest dobrym pomysłem. Nie ma na nich żadnego zabezpieczenia typów, co oznacza, że debugowanie można przeprowadzić tylko w czasie wykonywania. Dzięki kolekcjom silnie wpisanym (które można uzyskać za pomocą LINQ2SQL lub frameworku jednostek) Twoje życie będzie o wiele łatwiejsze.
Edycja: Być może nie było jasne: dane = dobre, zbiory danych = zło. Jeśli używasz ADO.Net, możesz użyć obu tych technologii (EF, linq2sql, dapper, nhibernate, orm of the month), ponieważ zazwyczaj znajdują się one na szczycie ado.net. Zaletą jest to, że możesz znacznie łatwiej zaktualizować model, gdy zmieni się schemat, pod warunkiem, że masz odpowiedni poziom abstrakcji, wykorzystując generowanie kodu.
Adapter ado.net korzysta z dostawców, którzy ujawniają informacje o typie bazy danych, na przykład domyślnie korzysta z dostawcy serwera sql, możesz również podłączyć - na przykład - dostawcę postgress devart i nadal uzyskać dostęp do informacji o typie, które następnie pozwalają ci jak wyżej korzystać z twojego wyboru (prawie bezboleśnie - jest kilka dziwactw) - uważam, że Microsoft również zapewnia dostawcę Oracle. CAŁKOWITYM celem tego jest oderwanie się od implementacji bazy danych tam, gdzie to możliwe.
Wersja niezależna od dostawcy, oparta wyłącznie na interfejsach ADO.NET; 2 drogi:
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];
}
}
}
}
Zrobiłem kilka testów wydajności i drugie podejście zawsze było lepsze od pierwszego.
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
wygląda lepiej na oczach, ale adapter danych działa lepiej (aby nie mylić, że jedna baza danych przewyższa drugą, zapytania były różne). Różnica między nimi zależała jednak od zapytania. Powodem może być to, że podczas dodawania wierszy Load
wymagane jest sprawdzanie różnych ograniczeń wiersz po wierszu z dokumentacji podczas dodawania wierszy (jest to metoda włączona DataTable
), podczas gdy Fill
jest to na adapterach DataAdapters, które zostały zaprojektowane specjalnie do tego celu - szybkie tworzenie DataTables.
DataTable.Load()
z .BeginLoadData()
i .EndLoadData()
osiągnąć taką samą prędkość jak w przypadku DataSet
.
Model centralny: możesz go używać z dowolnego miejsca!
Wystarczy wywołać funkcję Below Format From do tej klasy
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);
Otóż to. to doskonała metoda.
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;
}
}