Как обработать исключение выражения DataColumn в одной строке, не заставляя все строки использовать значение по умолчанию?

Я пытаюсь использовать DataTable для выполнения вычислений над строками данных, используя свойство Expression для DataColumns. MSDN

Я обнаружил, что если при применении выражения к строкам возникает исключение, будет использовано значение по умолчанию. Это именно то, что я хочу для строки, в которой есть проблема. Проблема в том, что каждая последующая строка будет использовать значение по умолчанию вместо оценки выражения.

В этом примере начните с базовой таблицы, состоящей из двух столбцов и 10 строк. Первый столбец - это автоматически увеличиваемый столбец с диапазоном от -5 до 5. Второй столбец всегда равен 3.

Я добавляю третий столбец с выражением, которое делит столбец "3" на первый столбец. Это вызовет исключение div0 для одной строки.

Для этой строки я хочу использовать значение по умолчанию, которое я предоставил. Это так, но также применяет значение по умолчанию к 4 оставшимся строкам.

Выход:

-5 3 -0.6
-4 3 -0.75
-3 3 -1
-2 3 -1.5
-1 3 -3
0 3 -33   //Expected
1 3 -33   //I want it to continue evaluating the expression, not default 
2 3 -33
3 3 -33
4 3 -33

Как добавить обработку, чтобы в случае проблем с отдельной строкой она использовала значение по умолчанию, продолжая использовать выражение для последующих строк?

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

Полный код для воспроизведения этого:

using System;
using System.Data;

namespace DataSetExpressionTest
{
    public class SO
    {
        private static DataTable table = null;

        private static void Main(string[] args)
        {
            table = CreateBaseTable(); 

            //If there is a problem only in some rows of the table, the rows before the error are calculated using the expression. All rows afrer use the default value
            DataColumn onlyOneException = new DataColumn()
            {
                ColumnName = "One-Ex",
                Expression = "third / index",
                DefaultValue = -33
            };

            AddCalculationToTable(onlyOneException);

            PrintDataTable(table);
            Console.ReadLine();
        }

        private static void AddCalculationToTable(DataColumn calculationColumn)
        {
            //You can wrap individual stats in try/catch blocks. If there is an exception in a calc, it will use the default value specified
            try
            {
                table.Columns.Add(calculationColumn);
            }
            catch (Exception e)
            {
                Console.WriteLine("Caught a calculation exception while adding column {0}. Will use default value instead!!", calculationColumn.ColumnName);
            }
        }

        private static DataTable CreateBaseTable()
        {
            DataTable table = new DataTable();

            // Create 3s column.
            DataColumn threeColumn = new DataColumn
            {
                DataType = Type.GetType("System.Decimal"),
                ColumnName = "third",
                DefaultValue = 3
            };

            //Create icrementing index column
            DataColumn indexColumn = new DataColumn
            {
                DataType = Type.GetType("System.Decimal"),
                ColumnName = "index",
                AutoIncrement = true,
                AutoIncrementSeed = -5
            };

            // Add columns to DataTable.
            table.Columns.Add(indexColumn);
            table.Columns.Add(threeColumn);

            for (var i = 0; i < 10; i++)
            {
                table.Rows.Add(table.NewRow());
            }
            return table;
        }

        public static void PrintDataTable(DataTable table)
        {
            foreach (DataColumn column in table.Columns)
            {
                Console.Write(column.ColumnName + " ");
            }

            Console.WriteLine();

            foreach (DataRow dataRow in table.Rows)
            {
                foreach (var item in dataRow.ItemArray)
                {
                    Console.Write(item + " ");
                }
                Console.WriteLine();
            }
        }
    }
}

0 ответов

Другие вопросы по тегам