using System;
using System.Data;
using System.Data.SqlClient;
publicclassPullDataTest
{
// your data tableprivate DataTable dataTable = new DataTable();
publicPullDataTest()
{
}
// your method to pull data from database to datatable publicvoidPullData()
{
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)
Dabblernl
@ yonan2236 Как насчет наличия выходных параметров из t sql рядом с datatable? как получить выходной параметр тоже? Является ли это возможным? Образец?
Ахмад Эбрахими
1
Этот код подвержен ошибкам, поэтому использовать доступные ресурсы таким образом не рекомендуется. Пожалуйста, смотрите ответ @Tim Rogers для чистого решения.
Xan-Kun Clark-Davis
Кроме того, взгляните на LINQ (если еще не сделали этого), так как он действительно может творить чудеса :-)
Ксан-Кун Кларк-Дэвис
78
var table = new DataTable();
using (var da = new SqlDataAdapter("SELECT * FROM mytable", "connection string"))
{
da.Fill(table);
}
@ Xan-KunClark-Davis: Код в принятом ответе приводит к утечке ресурсов при возникновении исключения. Вы могли бы не usingтак сильно презирать, если бы понимали его полный эквивалент.
Бен Фойгт
@ Xan-KunClark-Davis Почему ты презираешь Using?? Это похоже на презрение Withили Try-Catch. Я наоборот; Я разочарован, когда это не поддерживается классом.
SteveCinq
12
Много способов.
Используйте 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 или entity framework) ваша жизнь станет намного проще.
Изменить: Возможно, я не понял: Datatables = хорошо, наборы данных = зло. Если вы используете ADO.Net, вы можете использовать обе эти технологии (EF, linq2sql, dapper, nhibernate, orm of the month), поскольку они обычно находятся поверх ado.net. Преимущество, которое вы получаете, заключается в том, что вы можете намного проще обновлять свою модель по мере изменения вашей схемы, при условии, что у вас есть правильный уровень абстракции, используя генерацию кода.
Адаптер ado.net использует поставщиков, которые предоставляют информацию о типе базы данных, например, по умолчанию он использует поставщик сервера sql, вы также можете подключить - например, поставщик постгресса devart и по-прежнему получать доступ к информации о типе, которая затем будет позволяет вам, как указано выше, использовать выбранный вами orm (почти безболезненно - есть несколько причуд) - я считаю, что Microsoft также предоставляет поставщика Oracle. ВСЯ цель этого - абстрагироваться от реализации базы данных, где это возможно.
Типизированные наборы данных имеют безопасность типов и строго типизированные коллекции, как и EF. Но это только тогда, когда ваше приложение тесно связано с базой данных. Если вы пишете инструмент, который должен работать с множеством разных баз данных, безопасность типов - безнадежное желание.
Росс Прессер
1
Типизированные наборы данных в .net - это ужасное творение безумия и горя xml. Я никогда не работал в месте, которое готово принять накладные расходы на поддержание всего этого для типизированных наборов данных микрософтов. Я не думаю, что в наши дни даже Microsoft предлагает это разумно. Что касается безопасности типов с несколькими базами данных, конечно, вы можете это получить - дело в том, что вы конвертируете ее в типизированную коллекцию как можно скорее и передаете ее, чтобы ограничить проблемы типа определенным местом. Orms поможет в этом и отлично работает с несколькими базами данных. Если вам не нравится EF, используйте что-нибудь более легкое, например dapper.
Джон Николас
1
Вы меня не поняли. Если вы пишете инструмент общего назначения, который не знает, к какой базе данных он будет подключаться, то безопасность типов - безнадежное желание.
Росс Прессер
1
Sql предоставляется. Кроме того, если вы не знаете, что это за база данных, то почему она вообще должна быть базой данных? Каково было бы применение такого универсального инструмента? Если вам когда-нибудь понадобится подключиться к базам данных, которые действительно настолько радикально отличаются друг от друга, вы бы абстрагировались от него за шаблоном репозитория, а затем внутри этого вам понадобились бы другие специализированные адаптеры баз данных, и тогда вы бы узнали о специфике. Дело в том, что у потребляющего кода есть ожидания типа -> утверждения типа в адаптере. Ваше ограничение означает, что вы не имеете представления о языке базы данных и не можете делать запросы.
Джон Николас
3
Предположим, вы пишете клон SSMS?
Росс Прессер
9
Версия, не зависящая от производителя, полагается исключительно на интерфейсы 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];
}
}
}
}
Я провел некоторое тестирование производительности, и второй подход всегда превосходил первый.
Read1выглядит лучше на глазах, но адаптер данных работает лучше (чтобы не сбить с толку тот факт, что одна база данных превзошла другую, все запросы были разными). Однако разница между ними зависела от запроса. Причина может заключаться в том, что при добавлении строк (это метод на ) Loadтребуется проверка различных ограничений построчно из документации,DataTable а Fillна DataAdapters, которые были разработаны именно для этого - быстрое создание DataTables.
Вы должны окружать DataTable.Load()с .BeginLoadData()и .EndLoadData()достичь той же скоростью, с DataSet.
Никола Богданович
1
Центрированная модель: вы можете использовать ее откуда угодно!
Вам просто нужно вызвать ниже формат из вашей функции в этот класс
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);
Вот и все. это идеальный метод.
publicclassDbConnectionHelper {
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 Stringif (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;
}
}
Ответы:
Вот, попробуйте (это всего лишь псевдокод)
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)
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 или entity framework) ваша жизнь станет намного проще.
Изменить: Возможно, я не понял: Datatables = хорошо, наборы данных = зло. Если вы используете ADO.Net, вы можете использовать обе эти технологии (EF, linq2sql, dapper, nhibernate, orm of the month), поскольку они обычно находятся поверх ado.net. Преимущество, которое вы получаете, заключается в том, что вы можете намного проще обновлять свою модель по мере изменения вашей схемы, при условии, что у вас есть правильный уровень абстракции, используя генерацию кода.
Адаптер ado.net использует поставщиков, которые предоставляют информацию о типе базы данных, например, по умолчанию он использует поставщик сервера sql, вы также можете подключить - например, поставщик постгресса devart и по-прежнему получать доступ к информации о типе, которая затем будет позволяет вам, как указано выше, использовать выбранный вами orm (почти безболезненно - есть несколько причуд) - я считаю, что Microsoft также предоставляет поставщика 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
требуется проверка различных ограничений построчно из документации,DataTable
аFill
на DataAdapters, которые были разработаны именно для этого - быстрое создание DataTables.источник
DataTable.Load()
с.BeginLoadData()
и.EndLoadData()
достичь той же скоростью, с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; } }
источник