Тайм-аут команды Control TableAdapter глобально - PullRequest
4 голосов
/ 10 июня 2009

У меня есть DataSet с QueriesTableAdapter. Чтобы управлять SqlCommand.CommandTimeout, я добавил частичный класс QueriesTableAdapter с открытым методом ChangeTimeout.

partial class QueriesTableAdapter
{
    public void ChangeTimeout(int timeout)
    {
        foreach (System.Data.SqlClient.SqlCommand cmd in CommandCollection)
        {
            cmd.CommandTimeout = timeout;
        }
    }
}

Для каждого имеющегося у меня набора данных, который имеет QueriesTableAdapter, я могу установить CommandTimeout до выполнения.

using (NameSpace.DataSet.DataSetTableAdapters.QueriesTableAdapter ta =
new NameSpace.DataSet.DataSetTableAdapters.QueriesTableAdapter())
{
    ta.ChangeTimeout(3600);
    ta.DoSomething();
}

В большинстве случаев это работает хорошо, потому что «QueriesTableAdapter» назван для вас в конструкторе DataSet. Проблема, с которой я сталкиваюсь - это TableAdapters с уникальным именем. Например, если у меня есть DataTable с именем Person и TableAdaper с именем PersonTableAdapter, я должен написать частичный класс PersonTableAdapter так же, как я написал класс QueriesTableAdaper. У меня есть сотни DataTables с уникальными именами TableAdapter. Я не хочу создавать частичный класс для каждого из них. Как я могу получить к базовым объектам SqlCommand частичного класса глобальным способом?

Ответы [ 4 ]

11 голосов
/ 06 августа 2009

по какой-то причине .selectcommand моего адаптера был нулевым, поэтому мне пришлось пройти через объект CommandCollection, поэтому я решил опубликовать свое небольшое изменение на основе предыдущего ответа выше.

включает в себя:

using System.ComponentModel;
using System.Reflection;

Код:

private void ChangeTimeout(Component component, int timeout)
        {
            if (!component.GetType().Name.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;
            }

            command[0].CommandTimeout = timeout;            
        }
3 голосов
/ 10 июня 2009

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

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

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

        SqlDataAdapter adapter = adapterProp.GetValue(component, null) as SqlDataAdapter;
        if (adapter == null)
        {
            return;
        }

        adapter.SelectCommand.CommandTimeout = timeout;
    }

Затем вы можете назвать это так:

MyTableAdapter ta = new MyTableAdapter();
this.ChangeTimeout(ta,1000);

Я предполагаю, что, поскольку вы используете типизированные DataSet, вы все еще в .NET 2.0, поэтому я не стал делать это методом расширения.

1 голос
/ 09 октября 2010

BFree и подобные решения хорошо работают с отражением. Ниже приведено небольшое уточнение, которое, как мне кажется, дает более аккуратный код.

Вы также можете изменить базовый класс, который TableAdapter использует в конструкторе DataSet. Вы можете изменить базовый класс вашего TableAdapter на MyTableAdapterBaseClass или аналогичный, чтобы обеспечить необходимую вам функциональность. Вы можете быстро сделать это изменение на всех ваших адаптерах таблиц, выполнив «Поиск в файлах» и заменив файлы .xsd ваших наборов данных.

Вместо метода BFree на звонящем с подписью:

private void ChangeTimeout(Component component, int timeout)

затем вы можете создать метод в базовом классе вызываемого TableAdapter с подписью:

public void ChangeTimeout(int timeout)
0 голосов
/ 15 июля 2009

Я испробовал оба варианта и дал некоторые проблемы При первом ответе, какое пространство имен должно быть импортировано / использовано для объекта CommandCollection на адаптере ответа 2ns.SelectCommand возвращает нулевое значение

...