Изменяйте значения на лету во время SqlAdapter.Fill () - PullRequest
0 голосов
/ 05 мая 2010

Как правильно изменить значения на лету, когда они загружаются в DataTable с помощью SqlAdapter.Fill ()?

Я глобализировал сообщения журнала моего приложения. Целое число, обозначающее тип события и сериализованные данные, относящиеся к событию, сохраняется в базе данных, как показано ниже. Когда я отображаю зарегистрированные события через элемент управления DataGridView для пользователя, я интерполирую данные в строку форматирования.

event_type event_timestamp     event_details
============================================
3          2010-05-04 20:49:58 jsmith
1          2010-05-04 20:50:42 jsmith
...

В настоящее время я перебираю строки в DataTable для форматирования сообщений.

public class LogDataTable : DataTable
{
    public LogDataTable()
    {
        Locale = CultureInfo.CurrentCulture;
        Columns.AddRange(new DataColumn[] {
            new DataColumn("event_type", typeof(Int32)),
            new DataColumn("event_timestamp", typeof(DateTime)),
            new DataColumn("event_details", typeof(String))});
    }
}

...
using (SqlDataAdapter adapter = new SqlDataAdapter(...)) 
{
    adapter.SelectCommand.Parameters.AddRange(new Object[] {
       ...
    });
    adapter.Fill(table);
}
foreach (DataRow row in table.Rows)
{
    switch ((LogEventType)row["event_type"])
    {
       case LogEventType.Create:
           row["event_details"] = String.Format(Resources.Strings.LogEventCreateMsg, row["event_details"];
           break;
       case LogEventType.Create:
           row["event_details"] = String.Format(Resources.Strings.LogEventCreateMsg, row["event_details"];
           break;
       ...

Конечный результат, как показано, будет выглядеть так:

Type   Date and Time       Details
====================================================================
[icon] 2010-05-04 20:49:58 Failed login attempt with username jsmith
[icon] 2010-05-04 20:50:42 Successful login with username jsmith
...

Кажется бесполезным повторять набор результатов дважды - один раз, когда таблица заполняется адаптером, и снова выполнить замены. Я действительно хотел бы сделать замену на лету в моем классе LogDataTable, поскольку он заполняется.

Я попытался переопределить метод OnRowChanging в LogDataTable, который генерирует исключение InRowChangingEventException.

protected override void OnRowChanging(DataRowChangeEventArgs e)
{
    base.OnRowChanging(e);
    switch ((LogEventType)row["event_type"])
    ...

Я попытался переопределить метод OnRowChanged, который вызывает исключение StackOverflowException (я предполагаю, что его изменение вызывает повторный запуск метода до бесконечности?).

Я попытался переопределить метод OnTableNewRow, который не генерирует исключение, но, по-видимому, не вызывается (я полагаю, только когда пользователь добавляет строку в представление, которое я запретил).

Я был бы очень признателен за любую помощь, которую мне может оказать.

1 Ответ

1 голос
/ 05 мая 2010

ИМО, то, что ты сейчас делаешь, хорошо. Вы можете очень хорошо изменить элементы DataTable в памяти, как только они будут заполнены, вместо того, чтобы менять их на лету, поскольку это может ухудшить вашу производительность, поскольку это прерывает операцию ввода-вывода.

С другой стороны, если вы администратор БД, вы можете лучше ETL свой первый столбец:)

...