Установить CommandTimeout, используемый в строго типизированном DataSet TableAdapter? - PullRequest
7 голосов
/ 22 июня 2009

Преамбула:

Итак, за последние 5 лет в моей компании были написаны различные приложения и инструменты. К сожалению, многие из тех, кто разрабатывал эти приложения, использовали строго типизированные наборы данных, и я собираюсь сейчас запретить их в нашем магазине ...

Один из более крупных процессов, который использовал строго типизированные наборы данных, теперь истекает по времени ... Я намерен переписать весь процесс с помощью nHibernate в ближайшие несколько месяцев, но на данный момент мне нужно изменить время ожидания, чтобы наши пользователи использовать процесс, хотя и медленно ... К сожалению, Microsoft сделала методы commandtimeout приватными, поэтому я не могу получить к ним доступ напрямую.

Единственное решение, с которым я сталкивался до сих пор, - это создать частичный класс для каждого TableAdapter и включить в него методы тайм-аута ...

Это довольно неуклюже, поскольку это означало бы добавление частичных классов для нескольких TableAdapters ...

Кто-нибудь знает более эффективный способ справиться с этим?

Ответы [ 6 ]

3 голосов
/ 17 июня 2012

Я «решил» это с помощью отражения.(Хотя модель VS2010 позволяет отображать свойство Adapter, SelectCommand и т. Д. Будут, например, null до GetData.)

«Уродливый код, но функциональный код» IВ настоящее время я использую:

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();

Из-за отсутствия общей базы / интерфейсов на самом деле лучше набрать адаптер лучше (хотя, возможно, Component).

Удачное кодирование.

2 голосов
/ 23 июня 2009

Хорошо, насколько я могу судить, в этих ситуациях нет ярлыка / обходного пути. Спасибо Джону за попытку.

Мой лучший совет: не используйте наборы данных MS за пределами быстрого и грязного прототипирования ... Когда ваше приложение растет и нуждается в расширении, у вас остается только грязное пятно:)

2 голосов
/ 22 июня 2009

Вы не говорите, какой язык вы используете. Следующее есть в VB.NET, так как мне пришлось сначала найти такой пример:

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 голосов
/ 14 июля 2015

Я бы не стал связываться с кодом разработчика DataSet напрямую, потому что он будет изменен, если вы когда-нибудь что-нибудь обновите в конструкторе. Вместо этого создайте частичный класс для адаптера таблицы и передайте ему конструктор, который принимает параметр времени ожидания команды и вызывает конструктор без параметров.

Затем выполните цикл CommandCollection и установите время ожидания для переданного аргумента времени ожидания.

0 голосов
/ 20 января 2015

Я решил создать новый класс в файле DataSet.cs, который извлекает классы TableAdapter, а в конструкторе он проверяет App.config на время ожидания команды. Я также добавляю возможность указывать время ожидания команды для определенного адаптера таблицы и, если его нет, проверить глобальное значение.

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 голосов
/ 18 сентября 2014

Я решил эту проблему легко. Я вошел в код конструктора набора данных (dataset1.designer.vb) и обнаружил следующие команды, от Me._commandCollection(0), Me._commandCollection(1) до Me._commandCollection(5), потому что у меня всего пять команд, которые выполняются для моей базы данных SQL Server 2008. В каждой (от 0 до 5) из этих команд я написал Me._commandCollection(0).CommandTimeout = 60, где я заменяю 0 на следующее число для четырех других команд. Каждая из пяти команд имеет блок кода, из которых два блока отображаются ниже, чтобы предоставить вам пример.

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, "", "", ""))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...