Đọc bảng SQL thành C # DataTable


Câu trả lời:


156

Đây, hãy thử cho cái này (đây chỉ là một mã giả)

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
Các datatabletrường phải được khởi tạo trước khi gọida.Fill(dataTable)
Dabblernl

@ yonan2236 Còn việc có tham số đầu ra từ t sql bên cạnh dữ liệu thì sao? làm thế nào để có được thông số đầu ra quá? Nó có khả thi không? Mẫu vật?
Ahmad Ebrahimi,

1
Mã này dễ bị lỗi và không nên sử dụng các tài nguyên có sẵn theo cách này. Vui lòng xem câu trả lời của @Tim Rogers để biết giải pháp sạch.
Xan-Kun Clark-Davis

Bên cạnh đó, có một cái nhìn tại LINQ (nếu chưa có) vì nó thực sự có thể làm một số ma thuật ở đây :-)
Xan-Kun Clark-Davis

78
var table = new DataTable();    
using (var da = new SqlDataAdapter("SELECT * FROM mytable", "connection string"))
{      
    da.Fill(table);
}

7
@ Xan-KunClark-Davis: Mã trong câu trả lời được chấp nhận sẽ làm rò rỉ tài nguyên nếu một ngoại lệ được đưa ra. Bạn có thể không coi thường usingnhiều như vậy nếu bạn hiểu hoàn toàn tương đương của nó.
Ben Voigt

@ Xan-KunClark-Davis Tại sao bạn lại khinh thường Using?? Điều đó giống như khinh Withhoặc Try-Catch. Tôi là người ngược lại; Tôi thất vọng khi nó không được hỗ trợ bởi một lớp học.
SteveCinq

12

Rất nhiều cách.

Sử dụng ADO.Net và sử dụng điền vào bộ điều hợp dữ liệu để nhận 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);
}

Sau đó, bạn có thể lấy bảng dữ liệu ra khỏi tập dữ liệu.

Lưu ý trong tập dữ liệu câu trả lời ủng hộ không được sử dụng, (Nó xuất hiện sau câu trả lời của tôi)

// create data adapter
SqlDataAdapter da = new SqlDataAdapter(cmd);
// this will query your database and return the result to your datatable
da.Fill(dataTable);

Cái nào tốt hơn cho tôi.

Tôi thực sự khuyên bạn nên xem xét khung thực thể mặc dù ... sử dụng các tệp dữ liệu và bộ dữ liệu không phải là một ý tưởng tuyệt vời. Không có loại an toàn trên chúng, có nghĩa là việc gỡ lỗi chỉ có thể được thực hiện trong thời gian chạy. Với các bộ sưu tập được đánh máy mạnh mẽ (mà bạn có thể nhận được từ việc sử dụng LINQ2SQL hoặc khung thực thể), cuộc sống của bạn sẽ dễ dàng hơn rất nhiều.

Chỉnh sửa: Có lẽ tôi không rõ ràng: Datatables = good, datasets = evil. Nếu bạn đang sử dụng ADO.Net thì bạn có thể sử dụng cả hai công nghệ này (EF, linq2sql, dapper, nhibernate, orm of the month) vì chúng thường nằm trên ado.net. Lợi thế bạn nhận được là bạn có thể cập nhật mô hình của mình dễ dàng hơn nhiều khi lược đồ của bạn thay đổi với điều kiện bạn có mức độ trừu tượng phù hợp bằng cách tận dụng khả năng tạo mã.

Bộ điều hợp ado.net sử dụng các nhà cung cấp hiển thị thông tin loại của cơ sở dữ liệu, ví dụ: theo mặc định, nó sử dụng nhà cung cấp máy chủ sql, bạn cũng có thể cắm vào - ví dụ - nhà cung cấp dịch vụ đăng xuất và vẫn có quyền truy cập vào thông tin loại mà sau đó sẽ cho phép bạn như trên sử dụng orm của bạn lựa chọn (hầu như không đau - có một vài điều kỳ quặc) - tôi tin rằng Microsoft cũng cung cấp một nhà cung cấp oracle. Mục đích TOÀN BỘ của việc này là trừu tượng hóa việc triển khai cơ sở dữ liệu nếu có thể.


1
Tập dữ liệu đã nhập có độ an toàn về kiểu và các tập hợp được đánh mạnh, giống như EF. Nhưng những điều đó chỉ dành cho khi ứng dụng của bạn được kết hợp chặt chẽ với cơ sở dữ liệu. Nếu bạn đang viết một công cụ phải hoạt động với nhiều cơ sở dữ liệu khác nhau, thì an toàn khi nhập là một mong muốn vô vọng.
Ross Presser

1
Các tập dữ liệu được nhập trong .net là một sự sáng tạo khủng khiếp của sự điên rồ và khốn nạn của xml. Tôi chưa bao giờ làm việc ở một nơi sẵn sàng chấp nhận chi phí duy trì tất cả những điều đó cho một bộ dữ liệu đã nhập microsofts. Tôi không nghĩ rằng ngay cả microsoft cũng cho thấy nó hợp lý trong những ngày này. Đối với an toàn kiểu với nhiều cơ sở dữ liệu, tất nhiên bạn có thể nhận được nó - vấn đề là bạn chuyển đổi nó thành bộ sưu tập đã nhập càng sớm càng tốt và chuyển nó để bạn hạn chế các vấn đề về kiểu ở một nơi cụ thể. Orms sẽ giúp bạn điều đó và hoạt động hoàn toàn tốt với nhiều cơ sở dữ liệu. Nếu bạn không thích EF, hãy sử dụng thứ gì đó nhẹ hơn như dapper.
John Nicholas

1
Bạn không hiểu tôi. Nếu bạn đang viết một công cụ có mục đích chung mà không biết nó sẽ kết nối với loại cơ sở dữ liệu nào, thì việc nhập an toàn là một mong muốn vô vọng.
Ross Presser

1
Sql được đưa ra. Ngoài ra, nếu bạn không biết loại cơ sở dữ liệu nào thì tại sao nó thậm chí phải là cơ sở dữ liệu? Ứng dụng của một công cụ chung chung như vậy sẽ như thế nào? Nếu bạn cần kết nối với các cơ sở dữ liệu thực sự khác biệt hoàn toàn, bạn sẽ tóm tắt nó đằng sau một mẫu kho lưu trữ và bên trong đó bạn sẽ cần các bộ điều hợp cơ sở dữ liệu chuyên biệt khác và tại thời điểm đó bạn sẽ biết về các chi tiết cụ thể. Thực tế là tiêu thụ mã có kỳ vọng kiểu -> xác nhận kiểu trong bộ điều hợp. Ràng buộc của bạn có nghĩa là bạn không có ý tưởng về ngôn ngữ cơ sở dữ liệu và do đó không thể truy vấn.
John Nicholas

3
Giả sử bạn đang viết một bản sao SSMS?
Ross Presser

9

Phiên bản độc lập với nhà cung cấp, chỉ dựa vào giao diện ADO.NET; 2 cách:

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

Tôi đã thực hiện một số thử nghiệm hiệu suất và cách tiếp cận thứ hai luôn hoạt động tốt hơn cách tiếp cận đầu tiên.

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

Read1trông đẹp mắt hơn, nhưng bộ điều hợp dữ liệu hoạt động tốt hơn (đừng nhầm lẫn rằng một db hoạt động tốt hơn cái kia, các truy vấn đều khác nhau). Tuy nhiên, sự khác biệt giữa hai tùy thuộc vào truy vấn. Lý do có thể là Loadyêu cầu các ràng buộc khác nhau phải được kiểm tra từng hàng từ tài liệu khi thêm các hàng (một phương pháp bật DataTable) trong khi Filltrên DataAdapters được thiết kế chỉ cho điều đó - tạo nhanh DataTables.


3
Bạn cần phải bao quanh DataTable.Load()với .BeginLoadData().EndLoadData()để đạt được cùng tốc độ với DataSet.
Nikola Bogdanović

1

Mô hình tập trung: Bạn có thể sử dụng nó từ bất kỳ đâu!

Bạn chỉ cần gọi định dạng dưới đây Từ hàm của bạn đến lớp này

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

Đó là nó. đó là phương pháp hoàn hảo.

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;
   }
  }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.