2010-04-08 819 views
8

Để kiểm tra xem tôi có thể kết nối với cơ sở dữ liệu của tôi, tôi thực thi đoạn mã sau:Kiểm tra kết nối sql mà không ném ngoại lệ

using (SqlConnection connection = new SqlConnection(myConnectionString)) 
{ 
    try 
    { 
     connection.Open(); 
     canConnect = true; 
    } 
    catch (SqlException) { } 
} 

này hoạt động ngoại trừ nó ném một ngoại lệ nếu kết nối thất bại. Có cách nào khác để kiểm tra một kết nối Sql mà không ném một ngoại lệ?

Edit: Để thêm độ chính xác, tôi yêu cầu nếu có một phương pháp đơn giản nào đó mà không cần phải mở kết nối và bắt ngoại lệ có thể xảy ra

+0

Tại sao bạn muốn tránh ngoại lệ? – CResults

Trả lời

12

Khi cố mở kết nối, không có cách nào để tránh ngoại lệ nếu không thể mở kết nối. Nó có thể được ẩn đi trong một chức năng ở đâu đó, nhưng bạn sẽ nhận được ngoại lệ, không có vấn đề gì.

Nó được thiết kế như thế này vì thường bạn mong đợi để có thể kết nối với cơ sở dữ liệu. Kết nối không thành công là ngoại lệ.

Điều đó đang được nói, bạn có thể kiểm tra trạng thái kết nối hiện tại bất kỳ lúc nào bằng cách kiểm tra thuộc tính State.

2

viết một phần mở rộng như vậy:

public static class Extension{ 
public static bool CanOpen(this SqlConnection connection){ 
    try{ 
    if(connection == null){ return false; } 

    connection.Open(); 
    var canOpen = connection.State == ConnectionState.Open; 
    connection.close(); 
    return canOpen; 
} 
catch{ 
    return false; 
} 
} 

Sau đó, bạn có thể tiêu thụ nó thích:

using(var connection = new SqlConnection(myConnectionString)){ 
     if(connection.CanOpen()){ 
     // NOTE: The connection is not open at this point... 
     // You can either open it here or not close it in the extension method... 
     // I prefer opening the connection explicitly here... 
    } 
} 

HTH.

+0

Câu trả lời hay nhưng dude, bạn đang ném một ngoại lệ – CResults

+0

@CResults: không có THROW trong khối catch của phương pháp mở rộng có hiệu quả ăn ngoại lệ đó. Tôi thích có ngoại lệ này ném, nhưng OP đã đề cập rằng ông không muốn một ngoại lệ ném khi kiểm tra nếu một kết nối có thể được mở ra, do đó giải pháp của tôi. – Sunny

+0

Quan tâm đến giải pháp này, _SqlConnection.Open() _ sẽ nhận được kết nối từ pool nếu có sẵn pooling. Sau đó, _State_ sẽ là _Open_ ngay cả khi kết nối bị hỏng (ví dụ TCP channel). Và sau đó ngoại lệ sẽ chỉ được nâng lên khi thực hiện một lệnh. Cách giải quyết là sử dụng _Connection.ChangeDatabase (Connection.Database), _ để kiểm tra xem kết nối có sẵn hay không. – JoeBilly

3

Nếu nó ném một ngoại lệ và bạn xử lý nó trong khối catch của bạn, bạn đã biết kết nối không thành công. Tôi nghĩ bạn đã trả lời câu hỏi của bạn.

0

Tôi nghĩ câu trả lời thực sự ở đây là ping.

string data = "ismyserverpingable"; 
byte[] buffer = Encoding.ASCII.GetBytes (data); 
int timeout = 120; 
PingReply reply = pingSender.Send ("google.com", timeout, buffer, options); 
if (reply.Status == IPStatus.Success) 
{ 
} 

Trừ khi bạn đang kiểm tra rõ ràng xem liệu kết nối sql có thể 9/10 bạn nên biết liệu có gì đó là máy chủ sql hay không. Điều này sẽ giúp bạn tiết kiệm rằng sử dụng bộ nhớ khó chịu của một ngoại lệ đó là những gì tôi đang cá cược bạn đang thực sự sau.

+0

http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ping.aspx – Arian

0

Bạn luôn có thể sử dụng lớp ConnectionStringBuilder và kiểm tra sự tồn tại của từng phần được yêu cầu bởi chuỗi kết nối trước khi thử mở.

Nếu chuỗi kết nối đúng, nhưng máy chủ cơ sở dữ liệu bạn đang kết nối bị ngắt, bạn vẫn sẽ nhận được excepton. Loại vô nghĩa để kiểm tra chất lượng của chuỗi nếu điểm cuối bạn đang kết nối có thể có khả năng ngoại tuyến.

0

Bạn không thể tránh ngoại lệ trong khi kết nối cơ sở dữ liệu nhưng có một số chức năng xử lý việc này rất tốt. Tôi đang sử dụng hàm này trả về true nếu kết nối tồn tại.

public static bool IsSQLConnectionAvailable() 
    { 
     SqlConnection _objConn = new SqlConnection(); 

     try 
     { 
      _objConn.ConnectionString = ConfigurationManager.ConnectionStrings["DefaultSQLConnectionString"].ConnectionString; 
      _objConn.Open(); 
     } 
     catch 
     { 
      return false; 
     } 
     finally 
     { 
      if (_objConn.State == ConnectionState.Open) 
       _objConn.Close(); 
     } 

     return true; 
    }