Przez długi czas miałem problem z pewną aplikacją w ASP.NET, a konkretnie z pewnym żądaniem do serwera. W niektórych wywołaniach, serwer po 30 sekundach działania, zwracał error code 500 (internal server error). W pierwszym odruchu, moja uwaga skupiła się na analizie timeout'ów po stronie aplikacji ASP: sesje, pule aplikacji. Jednak, jak się później okazało, problem leżał w wywołaniu zapytania do bazy SQL. W dostępie do bazy wykorzystuję DataSety. Okazuje się, że każdy obiekt klasy TableAdapter ma domyślnie ustawioną właściwość CommandTimeout na wartości 30 sekund. Problem w tym, że właściwość ta jest protected i nie ma bezpośredniej możliwości modyfikacji jej wartości. Rozwiązaniem jest nadpisanie właściwości CommandTimeout w klasie rozszerzającej (klasy TableAdapter są oznaczone jako 'partial'). Przykładowy kod realizujący to zadanie:

 

namespace esklep_mag.DataSets {
    public partial class MyDS {
    }
}

namespace esklep_mag.DataSets.MyDSTableAdapters
{
    public partial class QueriesTableAdapter
    {
        public int CommandTimeout
        {
            set
            {
                for (int i = 0; (i < this.CommandCollection.Length); i = (i + 1))
                {
                    if ((this.CommandCollection[i] != null))
                    {
                        this.CommandCollection[i].CommandTimeout = value;
                    }
                }
            }
        }
    }
}

 

 

(najprostszą metodą na wygenerowanie tej klasy w osobnym pliku jest otworzenie DataSet'a w designerze, kliknięcie prawym przyciskiem myszy na wybranym adapterze i wybranie 'View code')


Tak przygotowany adapter możemy wykorzystać w kodzie tak:

 

DataSets.MyDSTableAdapters.QueriesTableAdapter qta = new esklep_mag.DataSets.MyDSTableAdapters.QueriesTableAdapter();
            qta.CommandTimeout = 480;
qta.GetData(...

 

W przypadku korzystania z adaptera jako źródła danych dla obiektu klasy ObjectDataSource, ustawienia czasu trwania zapytania możemy dokonać w zdarzeniu:

 

protected void ObjectDataSource1_ObjectCreated(object sender, ObjectDataSourceEventArgs e)
        {
            DataSets.TestsDBTableAdapters.QueriesTableAdapter qAda = e.ObjectInstance as DataSets.TestsDBTableAdapters.QueriesTableAdapter;
qAda.CommandTimeout = 480;
            
        }