Проверьте, какие столбцы были изменены в DataTable или datarow


Меня попросили обновить бизнес-правило, чтобы быть добавлены в определенном столбце. Потому что наш уровень данных использует только наборы данных в качестве интерфейса к базе данных, что мы работаем с бизнес-уровня.

Вот я создал несколько объектов DataTable и datarow объект расширений для этого businessrule и хотелось бы ваше мнение о том, что я, возможно, пропустили. Этот метод я использую для поиска изменения:

private static bool hasColumnChanged(StringComparison stringComparison, bool ignoreWhitespace, DataRow row, DataColumn col)
{
    bool isEqual = true;
    if (row[col, DataRowVersion.Original] != DBNull.Value && row[col, DataRowVersion.Current] != DBNull.Value)
    {
        if (ignoreWhitespace)
            isEqual = row[col, DataRowVersion.Original].ToString().Trim().Equals(row[col, DataRowVersion.Current].ToString().Trim(), stringComparison);
        else
            isEqual = row[col, DataRowVersion.Original].ToString().Equals(row[col, DataRowVersion.Current].ToString(), stringComparison);
    }
    else
        isEqual = row[col, DataRowVersion.Original].Equals(row[col, DataRowVersion.Current]);

    return !isEqual;
}

И это просто расширения, используя код:

public static List<DataColumn> GetChangedColumns(this DataTable table) 
{
    return table.GetChangedColumns(StringComparison.InvariantCultureIgnoreCase, false);
}
public static List<DataColumn> GetChangedColumns(this DataTable table, bool ignoreWhitespace)
{
    return table.GetChangedColumns(StringComparison.InvariantCultureIgnoreCase, ignoreWhitespace);
}
public static List<DataColumn> GetChangedColumns(this DataTable table, StringComparison stringComparison, bool ignoreWhitespace)
{
    if (table == null) throw new ArgumentNullException("table");

    List<DataColumn> columnsChanged = new List<DataColumn>();
    foreach (DataRow row in table.GetChanges().Rows)
    {
        foreach (DataColumn col in row.Table.Columns)
        {
            if (!columnsChanged.Contains(col) && hasColumnChanged(stringComparison, ignoreWhitespace, row, col))
                columnsChanged.Add(col);
        }
    }
    return columnsChanged;
}

public static List<DataColumn> GetChangedColumns(this DataRow row)
{
    return row.GetChangedColumns(StringComparison.InvariantCultureIgnoreCase, false);
}
public static List<DataColumn> GetChangedColumns(this DataRow row, bool ignoreWhitespace)
{
    return row.GetChangedColumns(StringComparison.InvariantCultureIgnoreCase, ignoreWhitespace);
}
public static List<DataColumn> GetChangedColumns(this DataRow row, StringComparison stringComparison, bool ignoreWhitespace)
{
    if (row == null) throw new ArgumentNullException("row");

    List<DataColumn> columnsChanged = new List<DataColumn>();
    foreach (DataColumn col in row.Table.Columns)
    {
        if (!columnsChanged.Contains(col) && hasColumnChanged(stringComparison, ignoreWhitespace, row, col))
            columnsChanged.Add(col);
    }
    return columnsChanged;
}

Чтобы проверить код, приведенный выше, я использую этот простой модульный тест:

[TestMethod]
public void DataTableAndDataRowGetChangedColumns()
{
    DataSet ds = GetDummyDataSet();
    ds.Tables[0].Rows[0][3] = DateTime.Now;
    ds.Tables[0].Rows[0][2] = ds.Tables[0].Rows[1][2].ToString() + " ";
    ds.Tables[0].Rows[0][1] = DBNull.Value;
    List<DataColumn> changesForRow = ds.Tables[0].Rows[0].GetChangedColumns(true);
    List<DataColumn> changesForTable = ds.Tables[0].GetChangedColumns(true);

    // For now we just verify if the amount of changes is the same (ez way out)
    Assert.IsTrue(changesForRow.Count.Equals(changesForTable.Count));
}

В нем я реализовал этот код, который проверяет, если есть другие datacolumns, которые были изменены:

List<DataColumn> columnsChanged = dsChanges.Tables[0].GetChangedColumns(true);
if(columnsChanged.Any(c=>!c.ColumnName.Equals("DateUntill", StringComparison.InvariantCultureIgnoreCase)))
    throw new BusinessException("This premium can not be changed, only DateUntill can still change");


54495
15
c#
задан 17 марта 2011 в 09:03 Источник Поделиться
Комментарии
1 ответ


  1. hasColumnChanged способ. В первую очередь , если у вас есть две почти одинаковые линии. Дублирование кода должны быть извлечены:

    if (row[col, DataRowVersion.Original] != DBNull.Value && row[col, DataRowVersion.Current] != DBNull.Value)  
    {
    string originalVersionToCompare = row[col, DataRowVersion.Original].ToString();
    string currentVersionToCompare = row[col, DataRowVersion.Current].ToString();
    if (ignoreWhitespace)
    {
    originalVersionToCompare = originalVersionToCompare.Trim();
    currentVersionToCompare = currentVersionToCompare.Trim();
    }
    isEqual = originalVersionToCompare.Equals(currentVersionToCompare, stringComparison);
    }

  2. Если у вас есть .Net версии 4.0, а затем 6 GetChangedColumns методов я бы рефакторинг в 2 с дополнительными параметрами.

  3. по каждому элементу внутри GetChangedColumns для объекта datarow выглядит как копипаста. Я не могу представить себе ситуацию, когда columnsChanged.Содержит(кол) будет справедливо в этот метод.

  4. hasColumnChanged , кажется, назвал неправильно. Следует hasCellChanged поскольку он проверяет на пересечении строки и столбца. Возможно также PascalCase?

  5. LINQify это!

    Оригинал:

    List<DataColumn> columnsChanged = new List<DataColumn>();
    foreach (DataRow row in table.GetChanges().Rows)
    {
    foreach (DataColumn col in row.Table.Columns)
    {
    if (!columnsChanged.Contains(col) && hasColumnChanged(stringComparison, ignoreWhitespace, row, col))
    columnsChanged.Add(col);
    }
    }
    return columnsChanged;

    Результат:

    return table.GetChanges().Rows.Cast<DataRow>()
    .SelectMany(dr => table.Columns.Cast<DataColumn>(), (row, column) => new {row, column})
    .Where(c => hasColumnChanged(stringComparison, ignoreWhitespace, c.row, c.column))
    .Select(c => c.column)
    .Distinct()
    .ToList();

  6. DateUntill - двойной л?

  7. Почему вы сравниваете вещи, бросая их в строку? Почему бы вам не сравнить их как объекты?

13
ответ дан 17 марта 2011 в 10:03 Источник Поделиться