2010-01-27 61 views
6

Tôi đang cố gắng tìm cách tối ưu (nhanh nhất so với dễ nhất) để truy cập mã SQL Server thông qua mã trong C#.Aproach tốt nhất để lấy dữ liệu sql từ C#

Khi tôi đang học từ sách, tôi đã gặp nhiều đề xuất thường yêu cầu tôi thực hiện việc này bằng cách kéo và thả. Tuy nhiên kể từ khi tôi muốn làm điều đó trong mã aproach đầu tiên là để có được dữ liệu theo số cột, nhưng bất kỳ sắp xếp lại trong truy vấn SQL (như thêm/loại bỏ cột) là đau đớn cho tôi để sửa chữa.

Ví dụ (đừng cười, một số mã cũng giống như 2 tuổi), tôi thậm chí mã hóa chức năng đặc biệt để vượt qua sqlQueryResult và kiểm tra xem nó là null hoặc không):

public static void exampleByColumnNumber(string varValue) { 

     string preparedCommand = @"SELECT TOP 1 [SomeColumn],[SomeColumn2] 

            FROM [Database].[dbo].[Table] 
        WHERE [SomeOtherColumn] = @varValue"; 
     SqlCommand sqlQuery = new SqlCommand(preparedCommand, Locale.sqlDataConnection); 
     sqlQuery.Prepare(); 
     sqlQuery.Parameters.AddWithValue("@varValue) ", varValue); 

     SqlDataReader sqlQueryResult = sqlQuery.ExecuteReader(); 
     if (sqlQueryResult != null) { 
      while (sqlQueryResult.Read()) { 
       string var1 = Locale.checkForNullReturnString(sqlQueryResult, 0); 
      string var2 = Locale.checkForNullReturnString(sqlQueryResult, 1); 
      } 
      sqlQueryResult.Close(); 
     } 
    } 

Sau đó tôi phát hiện ra nó có thể qua tên cột (mà có vẻ dễ dàng hơn để đọc với nhiều cột và rất nhiều thay đổi trật tự vv):

public static void exampleByColumnNames(string varValue) { 

     string preparedCommand = @"SELECT TOP 1 [SomeColumn],[SomeColumn2] 

            FROM [Database].[dbo].[Table] 
        WHERE [SomeOtherColumn] = @varValue"; 
     SqlCommand sqlQuery = new SqlCommand(preparedCommand, Locale.sqlDataConnection); 
     sqlQuery.Prepare(); 
     sqlQuery.Parameters.AddWithValue("@varValue) ", varValue); 

     SqlDataReader sqlQueryResult = sqlQuery.ExecuteReader(); 
     if (sqlQueryResult != null) { 
      while (sqlQueryResult.Read()) { 
       string var1 = (string) sqlQueryResult["SomeColumn"]; 
      string var2 = (string) sqlQueryResult["SomeColumn2"]; 
      } 
      sqlQueryResult.Close(); 
     } 
    } 

và thứ 3 ví dụ là bằng cách làm nó bằng tên cột nhưng sử dụng ToString() để chắc chắn rằng nó không giá trị null, hoặc bằng cách thực hiện If/else trên kiểm tra null.

public static void exampleByColumnNamesAgain(string varValue) { 

     string preparedCommand = @"SELECT TOP 1 [SomeColumn],[SomeColumn2], [SomeColumn3] 

            FROM [Database].[dbo].[Table] 
        WHERE [SomeOtherColumn] = @varValue"; 
     SqlCommand sqlQuery = new SqlCommand(preparedCommand, Locale.sqlDataConnection); 
     sqlQuery.Prepare(); 
     sqlQuery.Parameters.AddWithValue("@varValue) ", varValue); 

     SqlDataReader sqlQueryResult = sqlQuery.ExecuteReader(); 
     if (sqlQueryResult != null) { 
      while (sqlQueryResult.Read()) { 
       string var1 = (string) sqlQueryResult["SomeColumn"].ToString(); 
      DateTime var2; 
     DateTime.TryParse(sqlQueryResult["SomeColumn2"].ToString()); 

     int varInt = ((int) sqlQueryResult["SomeColumn3"] == null ? 0 : (int) sqlQueryResult["SomeColumn3"]; 

      } 
      sqlQueryResult.Close(); 
     } 
    } 

Xin lưu ý rằng tôi vừa mới tạo ví dụ này và có thể có lỗi chính tả hoặc lỗi cú pháp nhẹ, nhưng câu hỏi chính là cách tiếp cận tốt nhất, điều tồi tệ nhất (tôi biết cái đầu tiên là cái tôi không thích nhất). Tôi sẽ sớm phải bắt đầu/viết lại một số phần của ứng dụng dòng nhỏ 90k của tôi có ít nhất 3 ví dụ được sử dụng rộng rãi, vì vậy tôi muốn có được phương pháp tốt nhất cho tốc độ và tốt nhất là duy trì (hy vọng nó sẽ là cùng aproach).

Có thể có một số tùy chọn tốt hơn ở đó vì vậy hãy chia sẻ?

+1

Cậu nói 'optimization' sớm? – mjv

+0

Ý bạn là gì khi tối ưu hóa sớm? – MadBoy

+1

Nói chung nó có nghĩa là "đừng lo lắng về hiệu suất cho đến khi bạn hoàn thành". Bạn chưa biết liệu truy cập cơ sở dữ liệu có phải là nút cổ chai của bạn hay không, vì vậy đừng lo lắng về hiệu suất ngay bây giờ. Nếu bạn viết mã dễ đọc, dễ hiểu, dễ bảo trì, bạn sẽ hoàn thành nhanh hơn và ít lỗi hơn. Bạn luôn có thể quay lại và tối ưu hóa để có hiệu suất sau này. –

Trả lời

7

Dường như bạn có thể đang xem sách cũ. Nếu bạn định làm theo cách cũ, thì ít nhất bạn nên sử dụng các khối using. Tóm tắt:

using (var connection = new SqlConnection(connectionString)) 
{ 
    using (var command = new SqlCommand(commandString, connection)) 
    { 
     using (var reader = command.ExecuteReader()) 
     { 
      // Use the reader 
     } 
    } 
} 

Vẫn còn tốt hơn, hãy xem Entity Framework.

Links: Data Developer Center

+0

Câu hỏi của tôi là nhiều hơn về cách sử dụng đúng cách của tên cột so với số cột so với các giải pháp khác nhau. Tại sao mã của bạn cho tôi một số mẹo mới, nó không trả lời đầy đủ câu hỏi ban đầu của tôi :-) – MadBoy

+0

@MadBoy: thực ra, phần còn lại của câu trả lời của tôi _does_ giải quyết câu hỏi của bạn. Sử dụng khung thực thể và câu hỏi của bạn không phát sinh. Bạn chỉ cần sử dụng các thuộc tính có kiểu mạnh: 'var q = from c trong ngữ cảnh chọn c; foreach (var r in q) {// r.SomeColumn; r.SomeColumn2;} ' –

+0

@John Saunders - câu trả lời +1, nhưng không cần tất cả các tổ' {} '; bạn có thể xếp chồng các dòng 'using' và chỉ có một mức làm tổ duy nhất. Trong một ví dụ nhỏ nó không thực sự là một vấn đề (khác mà một sự lựa chọn của hương vị), nhưng trong một khối lớn của mã nó thực sự có thể giúp dễ đọc. – stevehipwell

2

Nếu đó là dễ bạn đang tìm kiếm, bạn không thể làm bất kỳ tốt hơn so với LINQ-to-SQL: -

http://weblogs.asp.net/scottgu/archive/2007/05/19/using-linq-to-sql-part-1.aspx

Nếu cơ sở dữ liệu SQL của bạn đã tồn tại, bạn có thể hoạt động sau vài giây.

Nếu không, tôi đồng ý với John.

+0

Có cơ sở dữ liệu đã được thiết lập và đang chạy và mọi người đang sử dụng ứng dụng của tôi.Kể từ khi tôi phải tiếp tục phát triển (và cải thiện nó ở những nơi mà tôi đã năm ngoái) tôi biết mã đã được viết lại nhiều ở một số nơi đặc biệt là kể từ khi tôi muốn nó được đa luồng. – MadBoy

+0

Bạn sẽ thiết lập và chạy, nhưng bạn sẽ bị ràng buộc với cấu trúc hiện tại của cơ sở dữ liệu của bạn. LINQ to SQL luôn tạo một ánh xạ một-một giữa các bảng và các lớp cơ sở dữ liệu. Nếu cơ sở dữ liệu của bạn thay đổi, thì các lớp của bạn cũng sẽ phải thay đổi. Entity Framework giải quyết vấn đề đó và cũng không giới hạn khi làm việc với SQL Server. –

+0

Tuyệt đối. Mặt khác, EF có đường cong học tập dốc hơn * nhiều *. Bạn sẽ thiết lập và chạy trong vài phút thay vì giây: P –

2

bạn nên có một cái nhìn vào những hướng dẫn,

[http://www.asp.net/learn/data-access/][1]

Tất cả công việc bạn đang có kế hoạch được đã được thực hiện.

có một cái nhìn tại cách này làm tương tự những gì bạn đang doinng

string preparedCommand = 
    @"SELECT TOP 1 [SomeColumn],[SomeColumn2], [SomeColumn3]  
    FROM [Database].[dbo].[Table] 
    WHERE [SomeOtherColumn] = @varValue"; 
    [1]: http://www.asp.net/learn/data-access/ 

More cách tốt hơn để làm điều tương tự trên là bằng cách sử dụng LINQ to SQL

var result = from someObject in SomeTable 
      where SomeColumnHasValue == ValueToCompare 
      select new { SomeColumn, SomeColumn1, SomeColumn2}; 
  • Không Loại an toàn Số phát hành
  • Trực quan hóa Cơ sở dữ liệu trong C# khi bạn hoạt động trên đó
  • tại thời gian biên dịch lỗi ít
  • mã ít hơn
  • năng suất cao hơn

Sau đây là một trong những nguồn lực lớn cho LINQ nếu bạn quan tâm

Hy vọng nó sẽ giúp

+0

Không chắc chắn ý bạn là gì khi hoàn thành và tự sử dụng nó. Tôi đã viết nó và nó hoạt động. Nhưng kể từ khi tôi viết nó và học C#/sql tại cùng một thời điểm, tôi tưởng tượng nó có các đoạn mã crappy mà sớm hay muộn tôi muốn sửa, đặc biệt là vì tôi cần thêm/cải thiện một số mã ở đây và ở đó nên tôi có thể cũng cập nhật một số phần thành mã tốt hơn mới hơn. – MadBoy

+0

"Tôi sẽ sớm phải bắt đầu/viết lại một số phần của ứng dụng dòng nhỏ 90k của tôi có ít nhất 3 ví dụ được sử dụng rộng rãi", Bạn nói đúng, tôi không hiểu đúng, tôi nghĩ, bạn sắp bắt đầu làm việc nó. Dù sao. Best Of Luck và hy vọng bạn thích làm việc với các phương thức truy cập dữ liệu mới khi bạn thay thế một số bit từ ứng dụng cũ của mình. –

+0

đã chỉnh sửa câu trả lời của tôi. –

1

Nếu bạn đang xem xét việc sử dụng ADO.net thẳng, bạn có thể muốn ra ngoài và tìm Khối ứng dụng truy cập dữ liệu của Thư viện doanh nghiệp của Microsoft. David Hayden có một số decent article mà đi vào một số chi tiết về việc sử dụng nó.

Chúc may mắn và hy vọng điều này sẽ giúp ích cho bạn.

1

Cách dễ nhất để thực hiện truy cập dữ liệu trong C#, theo ý tôi, là sử dụng DataSets đã nhập. Rất nhiều nó thực sự là kéo và thả, và nó thậm chí còn dễ dàng hơn trong .NET 2.0+ so với .NET 1.0/1.1.

Hãy nhìn vào bài viết này, trong đó nói về việc sử dụng DataSet đánh máy và TableAdapters:

Building a DAL using Strongly Typed TableAdapters and DataTables in VS 2005 and ASP.NET 2.0

Một gõ DataSet về cơ bản là một container cho dữ liệu của bạn. Bạn sử dụng một TableAdapter để điền vào nó (điều này xảy ra với SQL hoặc procs được lưu trữ, tùy theo cái nào bạn thích) và để cập nhật dữ liệu sau đó. Các tên cột trong mỗi DataTable trong DataSet của bạn được tự động phát sinh từ SQL được sử dụng để điền chúng; và các mối quan hệ giữa các bảng cơ sở dữ liệu được nhân đôi bởi các mối quan hệ giữa DataTables trong DataSet.

1

Không chuyển đổi dữ liệu thành chuỗi chỉ để phân tích cú pháp; DataReaders có phương pháp để chuyển đổi dữ liệu SQL với các loại dữ liệu Net:

using (var connection = new SqlConnection(Locale.sqlDataConnection)) 
using (var command = new SqlCommand(preparedCommand, connection)) 
using (var reader = command.ExecuteReader()) 
{ 
    int stringColumnOrdinal = reader.GetOrdinal("SomeColumn"); 
    int dateColumnOrdinal = reader.GetOrdinal("SomeColumn2"); 
    int nullableIntColumnOrdinal = reader.GetOrdinal("SomeColumn3"); 
    while (reader.Read()) 
    { 
     string var1 = reader.GetString(stringColumnOrdinal); 
     DateTime var2 = reader.GetDateTime(dateColumnOrdinal); 
     int? var3 = reader.IsDBNull(nullableIntColumnOrdinal) ? null : (int?)reader.GetInt32(nullableIntColumnOrdinal); 
    } 
} 
+0

Cảm ơn, nó rất hữu ích. – MadBoy

+0

Bạn không thể có số nguyên NULL trong C#. Nên là: int? var3 = reader.IsDBNull (nullableIntColumnOrdinal)? 0: reader.GetInt32 (nullableIntColumnOrdinal); – Switch

+0

@Chizl, tôi không tạo ra một số nguyên null, tôi đang tạo một null 'int?'. Không chuyển đổi null thành zeroes, bạn không thể biết sự khác biệt giữa giá trị thiếu/null và giá trị bằng 0. –

0

tôi thử nghiệm nhiều cách khác nhau để lấy dữ liệu từ cơ sở dữ liệu SQL Server và tôi phải đối mặt với & tìm thấy cách nhanh nhất là sau đây:

Trước hết tạo lớp với phương thức tham số "IDataRecord" theo các thuộc tính bắt buộc của bạn.

 class emp 
     { 
      public int empid { get; set; } 
      public string name { get; set; } 
      public static emp create(IDataRecord record) 
      { 
       return new emp 
       { 
        empid = Convert.ToInt32(record["Pk_HotelId"]), 
        name = record["HotelName"].ToString() 
       }; 
      } 
     } 

Bây giờ tạo ra phương pháp để có được dữ liệu như sau:

public List<S> GetData<S>(string query, Func<IDataRecord, S> selector) 
     { 
      using (var cmd = conn.CreateCommand()) 
      { 
       cmd.CommandText = query; 
       cmd.Connection.Open(); 
       using (var r = cmd.ExecuteReader()) 
       { 
        var items = new List<S>(); 
        while (r.Read()) 
         items.Add(selector(r)); 
        return items; 
       } 
      } 
     } 

Và sau đó gọi chức năng như:

var data = GetData<emp>("select * from employeeMaster", emp.create); 
Các vấn đề liên quan