2009-07-28 21 views

Trả lời

10

tôi đã điều tra vấn đề này một chút ngày hôm nay và đưa ra các giải pháp sau đây dựa trên một vài nguồn Ý tưởng. là tạo ra một lớp cơ sở cho bộ điều hợp bảng quá thừa hưởng làm tăng thời gian chờ cho tất cả các lệnh trong bộ điều hợp bảng mà không cần phải viết lại quá nhiều mã hiện có. Nó phải sử dụng sự phản chiếu vì các bộ điều hợp bảng được tạo ra không kế thừa bất kỳ thứ gì hữu ích. cho thấy một hàm công cộng để thay đổi thời gian chờ nếu bạn muốn xóa những gì tôi đã sử dụng trong hàm tạo và sử dụng nó.

using System; 
using System.Data.SqlClient; 
using System.Reflection; 

namespace CSP 
{ 
    public class TableAdapterBase : System.ComponentModel.Component 
    { 
     public TableAdapterBase() 
     { 
      SetCommandTimeout(GetConnection().ConnectionTimeout); 
     } 

     public void SetCommandTimeout(int Timeout) 
     { 
      foreach (var c in SelectCommand()) 
       c.CommandTimeout = Timeout; 
     } 

     private System.Data.SqlClient.SqlConnection GetConnection() 
     { 
      return GetProperty("Connection") as System.Data.SqlClient.SqlConnection; 
     } 

     private SqlCommand[] SelectCommand() 
     { 
      return GetProperty("CommandCollection") as SqlCommand[]; 
     } 

     private Object GetProperty(String s) 
     { 
      return this.GetType().GetProperty(s, BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.Instance).GetValue(this, null); 
     } 
    } 
} 
1

Nói tập dữ liệu của bạn được gọi là MySET.
Có một bảng gọi là MyTable

MySETTableAdapters.MyTableTableAdapter fAdapter = 
    new MySETTableAdapters.MyTableTableAdapter(); 
fAdapter.Adapter.SelectCommand.CommandTimeout = <fill inyour value here>; 
+0

-1 Điều này sẽ không hoạt động vì một 'TableAdapter' được đánh máy mạnh không hiển thị thuộc tính' Adapter', nó là 'riêng tư'. Vì vậy, cách duy nhất ngoài việc refelction là mở rộng lớp partial của 'TableAdapter' để công khai nó. –

2

Trong một số trường hợp, bạn không thể truy cập các thành viên như Adaptor trong lớp học của bạn, vì chúng được định nghĩa là tin đến lớp.

May mắn thay, trình hướng dẫn sẽ tạo các lớp học một phần, có nghĩa là bạn có thể mở rộng chúng. Như được mô tả trong [chủ đề này bởi Piebald] [1], bạn có thể viết thuộc tính của riêng mình để đặt thời gian chờ trên các lệnh chọn.

Nói chung, bạn sẽ làm điều này:

partial class FooTableAdapter 
{ 
    /** 
    * <summary> 
    * Set timeout in seconds for Select statements. 
    * </summary> 
    */ 
    public int SelectCommandTimeout 
    { 
    set 
    { 
     for (int n=0; n < _commandCollection.Length; ++n) 
     if (_commandCollection[n] != null) 
      ((System.Data.SqlClient.SqlCommand)_commandCollection[n]) 
      .commandTimeout = value; 
    } 
    } 
} 

Lưu ý rằng tôi đã không thực sự cố gắng này bản thân mình, nhưng nó có vẻ như một giải pháp khả thi.

+0

Cảm ơn! Tôi đã không thể có được điều này để làm việc cho tôi vì _commandCollection là null. Tôi đã thực hiện một số cập nhật và đăng rằng đó là câu trả lời khác. –

9

Với một số sửa đổi nhỏ, ý tưởng của csl hoạt động tốt.

partial class FooTableAdapter 
{ 
    /** 
    * <summary> 
    * Set timeout in seconds for Select statements. 
    * </summary> 
    */ 
    public int SelectCommandTimeout 
    { 
    set 
    { 
      for (int i = 0; i < this.CommandCollection.Length; i++) 
       if (this.CommandCollection[i] != null) 
       this.CommandCollection[i].CommandTimeout = value; 
    } 
    } 
} 

Để sử dụng, chỉ cần đặt this.FooTableAdapter.CommandTimeout = 60; một nơi nào đó trước này.FooTableAdapter.Fill();


Nếu bạn cần thay đổi thời gian chờ trên nhiều bộ điều hợp bảng, bạn có thể tạo phương pháp mở rộng chung và sử dụng phương pháp phản chiếu để thay đổi thời gian chờ.

/// <summary> 
/// Set the Select command timeout for a Table Adapter 
/// </summary> 
public static void TableAdapterCommandTimeout<T>(this T TableAdapter, int CommandTimeout) where T : global::System.ComponentModel.Component 
{     
    foreach (var c in typeof(T).GetProperty("CommandCollection", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetProperty | System.Reflection.BindingFlags.Instance).GetValue(TableAdapter, null) as System.Data.SqlClient.SqlCommand[]) 
     c.CommandTimeout = CommandTimeout; 
} 

Cách sử dụng:

this.FooTableAdapter.TableAdapterCommandTimeout(60); 
this.FooTableAdapter.Fill(...); 

Đây là chậm hơn một chút. Và có khả năng xảy ra lỗi nếu bạn sử dụng sai loại đối tượng. (Theo như tôi biết, không có lớp "TableAdapter" mà bạn có thể giới hạn nó.)

0

Nếu bạn sử dụng một phần lớp, hãy làm cho bạn có đúng không gian tên. Có lẽ [tên bộ dữ liệu của bạn] + "TableAdapters' Ví dụ:.

namespace MyProject.DataSet1TableAdapters

4

Tôi đã gặp một số vấn đề khi sử dụng giải pháp của Mitchell Gilman mà cuối cùng tôi có thể giải quyết.

Trước hết, tôi cần đảm bảo sử dụng đúng không gian tên. Tôi đã mất một thời gian để tìm ra rằng tệp Designer cho bộ dữ liệu xsd thực sự chứa hai không gian tên, một cho bộ dữ liệu nói chung và một cho bộ điều hợp bảng. Vì vậy, điều đầu tiên cần lưu ý là không gian tên cho bộ điều hợp bảng nên được sử dụng, không phải cho tập dữ liệu nói chung.

Thứ hai, lệnh có thể không luôn được khởi tạo khi lệnh hết thời gian được sử dụng lần đầu tiên. Để giải quyết vấn đề này, tôi đã gọi lệnh InitCommandCollection nếu đây là trường hợp.

Vì vậy, các giải pháp thích nghi tôi sử dụng là

namespace xxx.xxxTableAdapters 

partial class FooTableAdapter 
{ 
    /** 
    * <summary> 
    * Set timeout in seconds for Select statements. 
    * </summary> 
    */ 
    public int SelectCommandTimeout 
    { 
    set 
    { 
     if (this.CommandCollection == null) 
       this.InitCommandCollection(); 

     for (int i = 0; i < this.CommandCollection.Length; i++) 
      if (this.CommandCollection[i] != null) 
      this.CommandCollection[i].CommandTimeout = value; 
    } 
    } 
} 

Hy vọng rằng sẽ rất hữu ích với mọi người!

0

Bạn có thể mở thư mục Properties, mở Settings.settings và thay đổi thuộc tính Timeout của chuỗi kết nối của bạn.

0

Tôi thích điều này; Nhấp chuột phải vào chức năng Fill() hoặc GetX() và nhấp vào Goto Defination từ trình đơn.

Bạn sẽ thấy Mã nguồn của DATATABLE. Và tìm;

private global::System.Data.SqlClient.SqlCommand[] _commandCollection; 

dòng lệnh từ lớp dataadapter của bạn. Và thay đổi riêng tư thành công khai.

Bây giờ bạn có thể truy cập _commandCollection và bạn có thể thay đổi tất cả các thuộc tính.

Nhưng hãy cẩn thận khi bạn thêm hoặc thay đổi bất kỳ biểu mẫu được điền THIẾT KẾ, công chúng sẽ được tư nhân một lần nữa bằng hệ thống tự động phát.

Và cũng có thể, khi bạn hoàn thành để gọi Điền hoặc Nhận Function bạn phải thiết lập lại _commandColleciton gọi chức năng này (InitCommandCollection())

public void InitCommandCollection() {} 

Chức năng này cũng là tư nhân bằng cách autogen, bạn phải thay đổi cho công chúng cũng!

Ví dụ:

dsIslemlerTableAdapters.tblIslemlerTableAdapter _t = new dsIslemlerTableAdapters.tblIslemlerTableAdapter(); 

dsIslemler.tblIslemlerDataTable _m = new dsIslemler.tblIslemlerDataTable(); 

_t._commandCollection[0].CommandText = "Select * From tblIslemler Where IslemTarihi>='' And IslemTarihi<=''"; 

_m = _t.GetData(); 

_t.InitCommandCollection(); 
1

Gọi ChangeTimeout Chức năng bằng cách cung cấp TableAdapter và Thời gian trong vài giây.

this.ChangeTimeout(this.taTest, 500); 

Chức năng:

private void ChangeTimeout(Component component, int timeout) 
{ 
    if (!component.GetType().FullName.Contains("TableAdapter")) { 
     return; 
    } 

    PropertyInfo adapterProp = component.GetType().GetProperty("CommandCollection", BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.Instance); 
    if (adapterProp == null) { 
     return; 
    } 

    SqlCommand[] command = adapterProp.GetValue(component, null) as SqlCommand[]; 

    if (command == null) { 
     return; 
    } 

    Interaction.command(0).CommandTimeout = timeout; 
} 
+0

Tương tác là gì? –

0

Dưới đây là một số mã ví dụ từ MSDN, sử dụng VB.NET:

Imports System.Data.SqlClient 
Namespace MyDataSetTableAdapters 
    Partial Class CustomersTableAdapter 
     Public Sub SetCommandTimeOut(ByVal timeOut As Integer) 
      For Each command As SqlCommand In Me.CommandCollection 
       command.CommandTimeout = timeOut 
      Next 
     End Sub 
    End Class 
End Namespace 

Khi nói đến thời gian để gọi một truy vấn dài, chỉ cần gọi phương thức SetCommandTimeOut trước khi truy vấn:

Dim ds As New MyDataSet 
Dim customersTA As New MyDataSetTableAdapters.CustomersTableAdapter 
' Increase time-out to 60 seconds 
customersTA.SetCommandTimeOut(60000) 
' Do the slow query 
customersTA.FillSlowQuery(ds.Customers) 
0

một Đây là một chút cũ bây giờ và nghi ngờ giải pháp này không liên quan đến tất cả mọi người, nhưng tôi đã kết thúc bằng cách sử dụng giải pháp AniPol's để ghi đè điều khiển ObjectDataSource như sau:

public class MyObjectDataSource : ObjectDataSource 
{ 
    public MyObjectDataSource() 
    { 
     this.ObjectCreated += this.MyObjectDataSource_ObjectCreated; 
    } 

    private void MyObjectDataSource_ObjectCreated(object sender, ObjectDataSourceEventArgs e) 
    { 
     var objectDataSourceView = sender as ObjectDataSourceView; 
     if (objectDataSourceView != null && objectDataSourceView.TypeName.EndsWith("TableAdapter")) 
     { 
      var adapter = e.ObjectInstance; 

      PropertyInfo adapterProp = adapter.GetType() 
       .GetProperty(
        "CommandCollection", 
        BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.Instance); 
      if (adapterProp == null) 
      { 
       return; 
      } 

      SqlCommand[] commandCollection = adapterProp.GetValue(adapter, null) as SqlCommand[]; 

      if (commandCollection == null) 
      { 
       return; 
      } 

      foreach (System.Data.SqlClient.SqlCommand cmd in commandCollection) 
      { 
       cmd.CommandTimeout = 120; 
      } 
     } 
    } 
} 
0

Mở rộng trên các câu trả lời đã rất hữu ích cho tableadapters rằng helpe d tôi rất nhiều, tôi cũng đã có nhu cầu đọc ra giá trị thời gian chờ thực tế. Do đó:

namespace XTrans.XferTableAdapters 
{ 

    public partial class FooTableAdapter 
    { 
     int? _timeout = null; 

     ///<summary> 
     ///Get or set the current timeout in seconds for Select statements. 
     ///</summary> 
     public int CurrentCommandTimeout 
     { 
      get 
      { 
       int timeout = 0; 

       if (_timeout != null) 
       { 
        timeout = (int)_timeout; 
       } 
       else 
       { 
        for (int i = 0; i < this.CommandCollection.Length; i++) 
         if (this.CommandCollection[i] != null) 
          timeout = this.CommandCollection[i].CommandTimeout; 
       } 
       return timeout; 
      } 

      set 
      { 
       if (this.CommandCollection == null) 
        this.InitCommandCollection(); 

       for (int i = 0; i < this.CommandCollection.Length; i++) 
        if (this.CommandCollection[i] != null) 
        { 
         this.CommandCollection[i].CommandTimeout = value; 
         _timeout = value; 
        } 
      } 

     } 
    } 

} 
0

Có vẻ là cách thuận tiện hơn để thực hiện việc này. Đây là tóm tắt nhanh về những gì tôi tìm thấy.

Giả sử tôi thêm dự án (thư viện lớp) được gọi là MyDB vào giải pháp của tôi. Vào dự án đó tôi thêm một DataSet gọi là "Data". Và vào tập dữ liệu đó, tôi kéo một bảng có tên là "X".

Những gì tôi nhận được trên bề mặt thiết kế là một đối tượng cho thấy rằng tôi có một đối tượng được gọi là "XTableAdapter".

Bây giờ tôi mở mã được tạo, Data.Designer.cs và tìm XTableAdapter. Khi tôi tìm thấy nó, tôi lưu ý rằng nó được chứa trong không gian tên MyDB.DataTableAdapters - mà chỉ là một nối của tên của dự án, "MyDB", tên của Số liệu, "Dữ liệu", và "TableAdapters".

Với điều đó trong tay, bây giờ tôi quay trở lại thư viện lớp, vẫn được gọi là Class1.cs (mà tôi sẽ bỏ qua bây giờ).

Tôi thay đổi không gian tên của nó từ MyDB thành MyDB.DataTableAdapters.

tôi thay đổi khai báo lớp để public partial class XTableAdapter, và làm cho nó trông như thế này:

using System.Data.SqlClient; 

namespace MyDB.DataTableAdapters 
{ 
    public partial class XTableAdapter 
    { 
     public void SetTimeout(int seconds) 
     { 
      foreach (SqlCommand cmd in CommandCollection) 
      { 
       cmd.CommandTimeout = seconds; 
      } 
     } 
    } 
} 

Trình tự gọi điện thoại khó có thể được rõ ràng hơn:

int TwoMinutes = 120;  
XTableAdapter.SetTimeout(TwoMinutes); 

Ít muss, ít ồn ào hơn, ít phản xạ hơn (tốt, không), ít lấp đầy hơn.

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