SQL Tablosunu C # DataTable olarak okuyun


Yanıtlar:


156

İşte, buna bir şans verin (bu sadece bir sözde koddur)

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
datatableAlan çağırmadan önce ilklendirilmelidirda.Fill(dataTable)
Dabblernl

@ yonan2236 Datatable yanında t sql'den çıktı parametresine sahip olmaya ne dersiniz? çıktı parametresi nasıl alınır? Mümkün mü? Örneklem?
Ahmad Ebrahimi

1
Bu kod hatalara meyillidir ve mevcut kaynakların bu şekilde kullanılması önerilmez. Temiz çözüm için lütfen @ Tim Rogers yanıtına bakın.
Xan-Kun Clark-Davis

Bunun dışında, LINQ'ya bir göz atın (henüz yapmadıysa), çünkü burada gerçekten biraz sihir yapabilir :-)
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: Kabul edilen cevaptaki kod, bir istisna atılırsa kaynakları sızdırır. usingTam karşılığını anladıysanız, bu kadar küçümsemeyebilirsiniz .
Ben Voigt

@ Xan-KunClark-Davis Neden hor görüyorsunuz Using? Bu küçümsemek gibi Withya da Try-Catch. Ben tersiyim; Bir sınıf tarafından desteklenmediğinde hayal kırıklığına uğradım.
SteveCinq

12

Bir çok yol.

Veri Tablosu almak için ADO.Net kullanın ve veri adaptörünü doldurun:

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

Daha sonra veri tablosunu veri kümesinden alabilirsiniz.

Yükseltilen cevap veri setinde not kullanılmıyor, (Cevabımdan sonra göründü)

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

Benimkine tercih edilir.

Yine de varlık çerçevesine bakmanızı şiddetle tavsiye ederim ... veri tablolarını ve veri kümelerini kullanmak harika bir fikir değil. Üzerlerinde tür güvenliği yoktur, bu da hata ayıklamanın yalnızca çalışma zamanında yapılabileceği anlamına gelir. Güçlü yazılmış koleksiyonlarla (LINQ2SQL veya varlık çerçevesini kullanarak elde edebileceğiniz) hayatınız çok daha kolay olacak.

Düzenleme: Belki de net değildim: Veri tabloları = iyi, veri kümeleri = kötü. ADO.Net kullanıyorsanız, bu teknolojilerin her ikisini de (EF, linq2sql, dapper, nhibernate, orm of the month) genellikle ado.net'in en üstünde yer aldıkları için kullanabilirsiniz. Elde ettiğiniz avantaj, kod üretiminden yararlanarak doğru soyutlama seviyesine sahip olmanız koşuluyla şema değişiklikleriniz kadar modelinizi çok daha kolay güncelleyebilmenizdir.

Ado.net bağdaştırıcısı, veritabanının tür bilgisini ortaya çıkaran sağlayıcıları kullanır, örneğin varsayılan olarak bir sql sunucu sağlayıcısı kullanır, ayrıca örneğin devart postgress sağlayıcısını bağlayabilir ve daha sonra tür bilgisine erişmeye devam edebilirsiniz. Yukarıdaki gibi tercih ettiğiniz sistemi kullanmanıza izin verin (neredeyse acısız bir şekilde - birkaç tuhaflık var) - Microsoft'un da bir oracle sağlayıcısı sağladığına inanıyorum. Bunun TÜM amacı, mümkün olan yerlerde veritabanı uygulamasından soyutlamaktır.


1
Yazılan veri kümeleri, tıpkı EF gibi, tür güvenliğine ve güçlü bir şekilde yazılmış koleksiyonlara sahiptir. Ancak bunlar yalnızca uygulamanızın veritabanına sıkı bir şekilde bağlı olduğu durumlar içindir. Birçok farklı veri tabanı ile çalışması gereken bir araç yazıyorsanız, güvenlik yazın umutsuz bir dilektir.
Ross Presser

1
.Net'te yazılan veri kümeleri, xml çılgınlığının ve üzüntülerinin korkunç bir ürünüdür. Bir microsofts yazılan veri kümeleri için tüm bunları korumanın ek yükünü kabul etmeye istekli bir yerde hiç çalışmadım. Bugünlerde Microsoft'un bile mantıklı olduğunu düşündüğünü sanmıyorum. Birden çok veri tabanında tür güvenliğine gelince, elbette bunu elde edebilirsiniz - önemli olan, onu en kısa sürede yazılı koleksiyona dönüştürmeniz ve bunu iletmeniz, böylece tür sorunlarını belirli bir yerle sınırlandırmanızdır. Orms bu konuda yardımcı olacak ve birden fazla veritabanıyla mükemmel şekilde çalışacaktır. EF'den hoşlanmıyorsanız, zarif gibi daha hafif bir şey kullanın.
John Nicholas

1
Sen beni anlamadın Ne tür bir veritabanına bağlanacağı hakkında hiçbir fikri olmayan genel amaçlı bir araç yazıyorsanız, güvenlik yazın umutsuz bir dilektir.
Ross Presser

1
Sql verilir. Ayrıca, ne tür bir veritabanı olduğunu bilmiyorsanız, o zaman neden bir veritabanı olması gerekiyor? Böyle genel bir aracın uygulaması ne olabilir? Gerçekten çok radikal bir şekilde farklı olan veritabanlarına bağlanmanız gerekirse, bir depo modelinin ardında ondan soyutlanırsınız ve bunun içinde farklı özel veritabanı adaptörlerine ihtiyacınız olur ve bu noktada ayrıntılar hakkında bilgi sahibi olursunuz. Gerçek şu ki, tüketen kodun bağdaştırıcıda tür beklentileri -> tür iddiaları vardır. Kısıtlamanız, veritabanı dili hakkında hiçbir fikriniz olmadığı ve dolayısıyla sorgulayamayacağınız anlamına gelir.
John Nicholas

3
Bir SSMS klonu yazdığınızı varsayalım?
Ross Presser

9

Satıcıdan bağımsız sürüm, yalnızca ADO.NET arayüzlerine dayanır; 2 yol:

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

Bazı performans testleri yaptım ve ikinci yaklaşım her zaman ilkinden daha iyi performans gösterdi.

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

Read1gözlerde daha iyi görünüyor, ancak veri bağdaştırıcısı daha iyi performans gösteriyor (bir db'nin diğerinden daha iyi performans gösterdiğini karıştırmamak için, sorguların hepsi farklıydı). İkisi arasındaki fark, sorguya bağlıydı. Bunun nedeni, yalnızca bunun için tasarlanmış DataAdapters üzerindeyken satır eklerken (bir yöntemi açık ) dokümantasyondanLoad çeşitli kısıtlamaların satır satır kontrol edilmesini gerektirmesi olabilir - DataTable'ların hızlı oluşturulması.DataTableFill


3
Sen çevreleyen gerekir DataTable.Load()ile .BeginLoadData()ve .EndLoadData()ile aynı hıza ulaşmak için DataSet.
Nikola Bogdanović

1

Ortalanmış Model: İstediğiniz yerden kullanabilirsiniz!

Bu sınıfa fonksiyonunuzdan Aşağıdaki Format çağrısı yapmanız yeterlidir.

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

Bu kadar. mükemmel bir yöntem.

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;
   }
  }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.