Лучше ли использовать имя столбца или индекс столбца в наборах данных .Net?

StackOverflow https://stackoverflow.com/questions/473205

Вопрос

При получении значений из DataRow лучше использовать имя столбца или индекс столбца?

Имя столбца более читабельно и его проще поддерживать:

int price = (int)dr["Price"];

Хотя индекс столбца работает быстрее (я думаю):

int price = (int)dr[3];

Будет ли использование имен столбцов нарушением, если вы решите запутать базу данных?

Это было полезно?

Решение

Я обычно предпочитаю удобочитаемость и понимание, а не скорость. Иди с именем. Вы можете (должны) использовать строковые константы, которые можно обновлять в одном месте, если вы решите изменить имена столбцов базы данных.

Другие советы

Доступ к столбцам / значениям строк через имена столбцов удобнее для чтения человеком и для прямой совместимости (если в будущем кто-то изменит порядок или количество столбцов).

Учет значений столбцов / строк через независимость от столбцов повышает производительность.

Итак, если вы хотите изменить какое-либо значение в одной / двух / ..... строках, имена столбцов в порядке. Но если вы хотите изменить какое-либо значение в тысячах строк, вам следует использовать индекс столбца, вычисляемый по имени столбца:

int ndxMyColumn = table.Columns.IndexOf( "MyColumn" );
foreach(DataRow record in table.Rows ) {
    record[ndxMyColumn] = 15;
}

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

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

Вывод кода ниже:

515 мс с ColumnIndex

1031мс с именем столбца

    static void Main(string[] args)
    {            
        DataTable dt = GetDataTable(10000, 500);
        string[] columnNames = GetColumnNames(dt);

        DateTime start = DateTime.Now;
        TestPerformance(dt, columnNames, true);

        TimeSpan ts = DateTime.Now.Subtract(start);
        Console.Write("{0}ms with ColumnIndex\r\n", ts.TotalMilliseconds);

        start = DateTime.Now;
        TestPerformance(dt, columnNames, false);
        ts = DateTime.Now.Subtract(start);
        Console.Write("{0}ms with ColumnName\r\n", ts.TotalMilliseconds);
    }

    private static DataTable GetDataTable(int rows, int columns)
    {
        DataTable dt = new DataTable();

        for (int j = 0; j < columns; j++)
        {
            dt.Columns.Add("Column" + j.ToString(), typeof(Double));
        }

        Random random = new Random(DateTime.Now.Millisecond);
        for (int i = 0; i < rows; i++)
        {
            object[] rowValues = new object[columns];

            for (int j = 0; j < columns; j++)
            {
                rowValues[j] = random.NextDouble();
            }

            dt.Rows.Add(rowValues);
        }

        return dt;
    }

    private static void TestPerformance(DataTable dt, string[] columnNames, bool useIndex)
    {
        object obj;
        DataRow row;

        for (int i =0; i < dt.Rows.Count; i++)
        {
            row = dt.Rows[i];

            for(int j = 0; j < dt.Columns.Count; j++)
            {
                if (useIndex)
                    obj = row[j];
                else
                    obj = row[columnNames[j]];
            }
        }
    }

    private static string[] GetColumnNames(DataTable dt)
    {
        string[] columnNames = new string[dt.Columns.Count];

        for (int j = 0; j < columnNames.Length; j++)
        {
            columnNames[j] = dt.Columns[j].ColumnName;
        }

        return columnNames;
    }

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

РЕДАКТИРОВАТЬ:

На самом деле, если бы вы действительно хотели использовать индексы столбцов, вы могли бы создать константы индексов столбцов и назвать константу именем столбца.Так:

PRIMARY_KEY_COLUMN_NAME_INDEX = 0

По крайней мере, это сделало бы его читабельным.

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

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

Мое мнение таково, что переходить на индексы следует только в том случае, если вы профилировали свой код, и это показалось узким местом. Я не думаю, что это произойдет.

Именование - это хорошо, оно помогает нашему ограниченному мозгу понимать проблемы и легче создавать ссылки. Вот почему нам дают имена, такие как Фред, Мартин, Джейми, а не человек [189333847], человек [138924342] и человек [239333546].

Если вы решили скрыть базу данных, изменив имена столбцов в будущем, вы можете использовать псевдонимы этих столбцов в своем запросе, чтобы сохранить работоспособность кода индексатора. Я предлагаю индексацию по имени.

Идите с именем, вы получите лучшие сообщения об ошибках:)

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

public class ExampleDataColumns
{
    public const string ID = "example_id";
    public const string Name = "example_name";
    ....    
}

Тогда я могу сослаться на это позже так:

row[ExampleDataColumns.ID]

Используйте имена столбцов для DataRow в том же ключе, что СУБД не будет набирать скорость, требуя от программистов указывать индекс столбца в SQL. Но, возможно, вы можете имитировать работу СУБД при выполнении оператора SELECT, внутри движка СУБД она запрашивает индекс / смещение столбцов столбцов, указанных в предложении SELECT, прежде чем пересекает строки, чтобы она могла работать быстрее.

Если вы действительно хотите набрать скорость, не делайте это const / enum (порядок столбцов может измениться в вашей базе данных или на уровне ORM). Сделайте это, как предложено TcKs (до фактического цикла):

int ndxMyColumn = table.Columns.IndexOf( "MyColumn" );
foreach(DataRow record in table.Rows ) {
    record[ndxMyColumn] = 15;
}

я использую рефлексию (не уверен, что это правильный способ назвать то, что я делаю), чтобы получить columnnameColumn из таблицы

нет " жесткое кодирование " лучше

  int price = (int)dr[DatableVar.PriceColumn];
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top