Читайте таблицю SQL у таблиці даних C #


92

Я прочитав багато публікацій про вставку таблиці даних у таблицю SQL, але чи є простий спосіб витягнути таблицю SQL у таблицю даних.


8
Ммм ... використовувати метод Fill на DataAdapter?
Джон Бледсо

Відповіді:


155

Ось, зробіть це (це просто псевдокод)

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();
    }
}

18
datatableПоле має бути инициализирована перед викликомda.Fill(dataTable)
Dabblernl

@ yonan2236 Що можна сказати про вихідний параметр з t sql біля таблиці даних? як отримати параметр виводу теж? Це можливо? Зразок?
Ахмад Ебрагімі

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);
}

7
@ Xan-KunClark-Davis: Код у прийнятій відповіді витікає з ресурсів, якщо виникає виняток. Ви можете не usingтак зневажати, якби зрозуміли його повний еквівалент.
Бен Войгт,

@ Xan-KunClark-Davis Чому б ти зневажав Using?? Це як зневажати Withабо Try-Catch. Я зворотний; Я розчарований, коли клас не підтримує.
SteveCinq

12

Багато шляхів.

Використовуйте ADO.Net та використовуйте заливку на адаптері даних, щоб отримати таблицю даних:

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 або фреймворку сутності) ваше життя стане набагато простішим.

Редагувати: Можливо, я не зрозумів: Datatables = добро, набори даних = зло. Якщо ви використовуєте ADO.Net, тоді ви можете використовувати обидві ці технології (EF, linq2sql, dapper, nhibernate або orm місяця), оскільки вони, як правило, розташовані на вершині ado.net. Перевага, яку ви отримуєте, полягає в тому, що ви можете набагато простіше оновити модель, оскільки ваша схема змінюється за умови, що ви маєте правильний рівень абстракції, використовуючи генерацію коду.

Адаптер ado.net використовує провайдери, які надають інформацію про тип бази даних, наприклад, за замовчуванням він використовує провайдера сервера sql, ви також можете підключити - наприклад, devart postgress провайдера і все одно отримати доступ до інформації про тип, яка потім дозволити вам, як зазначено вище, використовувати свій вибір (майже безболісно - є кілька примх) - я вважаю, що Microsoft також надає постачальника послуг оракула. ЦІЛОЮ метою цього є абстрагування від реалізації бази даних, де це можливо.


1
Типізовані набори даних мають безпеку типу та сильно набрані колекції, як і EF. Але це лише для випадків, коли ваш додаток тісно пов’язаний з базою даних. Якщо ви пишете інструмент, який повинен працювати з багатьма різними базами даних, безпека типу - безнадійне бажання.
Ross Presser

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];
            }
        }
    }
}

Я провів тестування продуктивності, і другий підхід завжди перевершував перший.

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.


3
Ви повинні оточувати 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);

Це воно. це ідеальний метод.

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;
   }
  }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.