2009-06-22 25 views
7

Lời nói đầu:Đặt CommandTimeout được sử dụng trong TableAdapter dữ liệu được đánh máy mạnh?

Vì vậy, trong 5 năm qua, các ứng dụng và công cụ khác nhau đã được viết tại công ty của tôi. Rất tiếc, nhiều người đã phát triển các ứng dụng này sử dụng bộ dữ liệu được nhập mạnh mẽ, tôi đang xem xét việc cấm chúng trong cửa hàng của chúng tôi ngay bây giờ ...

Một trong những quy trình lớn hơn sử dụng bộ dữ liệu được nhập mạnh mẽ hiện đã hết thời gian ... để viết lại toàn bộ quá trình bằng cách sử dụng nHibernate trong vài tháng tới nhưng trong thời điểm này tôi cần thay đổi thời gian chờ để cho phép người dùng sử dụng quy trình, mặc dù chậm ... Thật không may Microsoft đã thực hiện các phương pháp commandtimeout riêng tư nên tôi không thể truy cập chúng trực tiếp.

Giải pháp duy nhất tôi đã đi qua cho đến nay là để tạo ra một lớp học phần cho mỗi TableAdapter và bao gồm các phương pháp thời gian chờ có ...

này khá phiền phức vì nó sẽ có nghĩa là thêm các lớp học phần cho khá vài TableAdapters ...

Có ai biết cách hiệu quả hơn để xử lý việc này không?

Trả lời

2

Bạn không nói ngôn ngữ mình đang sử dụng. Sau đây là trong VB.NET kể từ khi tôi đã xảy ra để tìm thấy một ví dụ đầu tiên:

Namespace AdventureWorksPurchasingDSTableAdapters 
    Partial Public Class SalesOrderHeaderTableAdapter 
    Public Property SelectCommandTimeout() As Integer 
     Get 
     Return Adapter.SelectCommand.CommandTimeout 
     End Get 
     Set(ByVal value As Integer) 
     Adapter.SelectCommand.CommandTimeout = value 
     End Set 
    End Property 
    End Class 
End Namespace 
+0

Đúng, nhưng đó là những gì tôi đang cố gắng tránh làm ... Cá nhân rất dễ làm ... Nếu bạn có vài trăm bộ điều hợp bảng cho hàng trăm bộ dữ liệu thì nó thực sự không khả thi lắm. – Gary

+0

Tôi không thể nghĩ bạn có thể làm gì khác. Không có tài sản CommandTimeout toàn cầu. Nếu có, nó sẽ bằng cách nào đó phải thiết lập các thuộc tính SqlCommand.CommandTimeout riêng lẻ. –

+0

Tại sao người ta không thể điều chỉnh thuộc tính CommandTimeout trong Nhà thiết kế Dataset? Và tại sao nó vẫn còn 30 giây khi tôi thay đổi Thời gian chờ kết nối thành 300 giây? Btw, sự khác nhau giữa chúng là gì? Cảm ơn trước ... –

2

Ok, cho đến nay tôi có thể nói không có phím tắt/workaround cho những tình huống này. Cảm ơn John vì đã cố gắng.

lời khuyên tốt nhất của tôi là không sử dụng MS tập hợp dữ liệu bên ngoài của mẫu nhanh chóng và dơ bẩn ... Khi ứng dụng của bạn phát triển và cần phải được mở rộng bạn đã chỉ có những trái bẩn :)

+0

Đây là một cơ sở khá hẹp để loại bỏ các DataSets đã nhập. Tuy nhiên, đây là cơ sở tuyệt vời cho đề xuất tính năng trên Connect (http://connect.microsoft.com/visualstudio/). Khi bạn đã đăng đề xuất, hãy chỉnh sửa câu trả lời này cùng với URL của đề xuất để những người khác có thể bỏ phiếu cho mức độ quan trọng của chúng tôi. –

+0

Vâng, vấn đề này không phải là cơ sở duy nhất cho tuyên bố đó ... Vấn đề lớn nhất tôi có với bộ dữ liệu là thiếu mặc định thông minh ... Nếu tệp cấu hình của bạn không có chuỗi kết nối phù hợp trong đó thì mặc định cho bất kỳ chuỗi kết nối nào được tạo ra với ... Cảm giác ruột của tôi về vấn đề đó là trong bất kỳ tình huống nào có bất kỳ sự mơ hồ nào thì câu trả lời đúng chỉ là ném một ngoại lệ và chết ... – Gary

+0

Tôi sẽ đưa ra đề xuất vào Kết nối sau đêm trước này, tôi đã không bỏ qua đề xuất của bạn :) – Gary

3

tôi "giải quyết" điều này bằng cách sử dụng sự phản chiếu. (Trong khi model VS2010 cho phép lộ Adapter tài sản, SelectCommand, vv, sẽ null trước GetData, ví dụ.)

Các "mã xấu xí nhưng mã chức năng" Tôi hiện đang sử dụng:

void SetAllCommandTimeouts(object adapter, int timeout) 
{ 
    var commands = adapter.GetType().InvokeMember(
      "CommandCollection", 
      BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic, 
      null, adapter, new object[0]); 
    var sqlCommand = (SqlCommand[])commands; 
    foreach (var cmd in sqlCommand) 
    { 
     cmd.CommandTimeout = timeout; 
    } 
} 

// unfortunately this still requires work after a TableAdapter is obtained... 
var ta = new MyTableAdapter(); 
SetAllCommandTimeouts(ta, 120); 
var t = ta.GetData(); 

Nó không thực sự có thể để loại adapter tốt hơn (mặc dù có lẽ đến một Component), do thiếu cơ sở chung/giao diện.

Mã hóa vui vẻ.

+0

Rất hữu ích khi khắc phục sự cố của tôi. :) –

0

Tôi đã giải quyết vấn đề này dễ dàng. Tôi đã đi vào mã thiết kế của tập dữ liệu (dataset1.designer.vb) và tìm thấy các lệnh sau, Me._commandCollection(0), Me._commandCollection(1) đến Me._commandCollection(5), bởi vì tôi có năm lệnh tổng thực thi dựa trên cơ sở dữ liệu SQL Server 2008 của tôi. Trong mỗi (0 đến 5) của các lệnh này tôi đã viết Me._commandCollection(0).CommandTimeout = 60, trong đó tôi thay đổi 0 thành số tiếp theo cho bốn lệnh khác. Mỗi một trong năm lệnh có một khối mã, trong đó có hai khối xuất hiện bên dưới để cung cấp cho bạn một ví dụ.

Me._commandCollection = New Global.System.Data.SqlClient.SqlCommand(5) {} 

Me._commandCollection(0) = New Global.System.Data.SqlClient.SqlCommand() 

Me._commandCollection(0).Connection = Me.Connection 

Me._commandCollection(0).CommandTimeout = 60 

Me._commandCollection(0).CommandText = "SELECT MK_QR_SUB_AND_DETAIL.*" & _ "Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10)" & _ "FROM MK_QR_SUB_AND_DETAIL" 

Me._commandCollection(0).CommandType = Global.System.Data.CommandType.Text  

Me._commandCollection(1) = New Global.System.Data.SqlClient.SqlCommand() 

Me._commandCollection(1).Connection = Me.Connection 

Me._commandCollection(1).CommandTimeout = 60 

Me._commandCollection(1).CommandText = "dbo.spQtrRptTesting_RunInserts_Step1of4" 

Me._commandCollection(1).CommandType = Global.System.Data.CommandType.StoredProcedure 

Me._commandCollection(1).Parameters.Add(New Global.System.Data.SqlClient.SqlParameter("@RETURN_VALUE", Global.System.Data.SqlDbType.Int, 4, Global.System.Data.ParameterDirection.ReturnValue, 10, 0, Nothing, Global.System.Data.DataRowVersion.Current, False, Nothing, "", "", "")) 

Me._commandCollection(1).Parameters.Add(New Global.System.Data.SqlClient.SqlParameter("@pStartADate", Global.System.Data.SqlDbType.[Date], 3, Global.System.Data.ParameterDirection.Input, 10, 0, Nothing, Global.System.Data.DataRowVersion.Current, False, Nothing, "", "", "")) 

Me._commandCollection(1).Parameters.Add(New Global.System.Data.SqlClient.SqlParameter("@pEndADate", Global.System.Data.SqlDbType.[Date], 3, Global.System.Data.ParameterDirection.Input, 10, 0, Nothing, Global.System.Data.DataRowVersion.Current, False, Nothing, "", "", "")) 

Me._commandCollection(1).Parameters.Add(New Global.System.Data.SqlClient.SqlParameter("@pStartBDate", Global.System.Data.SqlDbType.[Date], 3, Global.System.Data.ParameterDirection.Input, 10, 0, Nothing, Global.System.Data.DataRowVersion.Current, False, Nothing, "", "", "")) 

Me._commandCollection(1).Parameters.Add(New Global.System.Data.SqlClient.SqlParameter("@pEndBDate", Global.System.Data.SqlDbType.[Date], 3, Global.System.Data.ParameterDirection.Input, 10, 0, Nothing, Global.System.Data.DataRowVersion.Current, False, Nothing, "", "", "")) 
+0

Cảnh báo: không bao giờ chỉnh sửa các tệp 'designer' theo cách thủ công. Đây là mã được tạo tự động, mọi thứ bạn viết trong đó có thể được ghi đè bởi Visual Studio khi nó sẽ tạo lại mã. –

0

Tôi đã quyết định tạo một lớp mới trong tệp DataSet.cs xuất phát từ các lớp TableAdapter và trong hàm tạo nó sẽ kiểm tra App.config cho các lệnh timetime. Tôi cũng thêm khả năng để chỉ định một thời gian lệnh ra cho một bộ chuyển đổi bảng cụ thể và nếu đó không phải là hiện tại, sau đó kiểm tra một giá trị toàn cầu.

public class ImprovedMyTableAdapter : MyTableAdapter 
{ 
    public ImprovedMyTableAdapter() 
     : base() 
    { 
     int parsedInt = int.MinValue; 
     string appSettingValue = System.Configuration.ConfigurationManager.AppSettings["MyTableAdapter_CommandTimeout"]; 
     if (string.IsNullOrEmpty(appSettingValue)) 
      appSettingValue = System.Configuration.ConfigurationManager.AppSettings["CommandTimeout"]; 
     if (!string.IsNullOrEmpty(appSettingValue) && int.TryParse(appSettingValue, out parsedInt)) 
     { 
      foreach (var command in this.CommandCollection) 
       command.CommandTimeout = parsedInt; 
     } 
    } 
} 
0

Tôi sẽ không gây rối với mã của nhà thiết kế DataSet trực tiếp b/c nó sẽ bị thay đổi nếu bạn cập nhật mọi thứ trong thiết kế. Thay vào đó, hãy tạo một lớp từng phần cho bộ điều hợp bảng và cung cấp cho nó một hàm tạo chấp nhận tham số timeout của lệnh và gọi hàm tạo parameterless.

Sau đó lặp qua CommandCollection và đặt thời gian chờ cho đối số hết thời gian chờ đã chuyển.

Các vấn đề liên quan