Pergunta

Ao recuperar valores a partir de um DataRow é melhor usar o nome da coluna ou coluna de índice?

O nome da coluna é mais legível e mais fácil de manter:

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

Enquanto índice da coluna é apenas mais rápido (eu acho):

int price = (int)dr[3];

Would nomes usando coluna quebrar se você decidir para ofuscar o banco de dados?

Foi útil?

Solução

I geralmente preferem a leitura e compreensão sobre a velocidade. Vá com o nome. Você poderia (deveria) constantes string uso que podem ser atualizados em um lugar se você decidir os nomes das colunas de banco de dados mudança.

Outras dicas

Acessando colunas / valores de linha através de nomes de coluna é melhor para e para diante-compatibilidade (se, no futuro, a fim alguém mudar ou contagem de colunas). Leitura humana

Accissing colunas / valores de linha via indeces coluna é melhor para o desempenho.

Então, se você quiser alterar algum valor em uma / duas / ..... linhas, os nomes das colunas são ok. Mas se você quiser alterar algum valor em milhares de linhas, você deve usar o índice de coluna computada a partir nome da coluna:

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

Completamente agress com os outros novamente. ir para facilitar a leitura e manutenção de excesso de velocidade. Eu, porém, teve um método genérico que precisava ser colunas nomeadas passado como parâmetros por isso fazia sentido para descobrir o que lá os índices de colunas eram.

Na análise comparativa abaixo usando o índice de coluna mostrou uma grande melhora por isso, se esta é uma área de estrangulamento ou uma parte crítica do desempenho do seu código pode valer a pena.

A saída do código abaixo é:

515ms com ColumnIndex

1031ms com ColumnName

    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;
    }

Eu acho que o nome da coluna é o melhor caminho a percorrer. É mais fácil determinar o que você está puxando, e a ordem das colunas é determinada pela instrução SELECT que poderia mudar em algum momento no futuro. Você pode argumentar o nome da coluna pode mudar também, mas eu acho que isso seria muito menos provável.

EDIT:

Na verdade, se você estava realmente empenhado em usar índices de coluna você pode criar constantes dos índices de coluna e nomear a constante o nome da coluna. Assim:

PRIMARY_KEY_COLUMN_NAME_INDEX = 0

Isso, pelo menos, torná-lo legível.

Depende do que você precisa. No meu caso, eu tinha uma situação onde a velocidade era primordial como eu estava realizando o processamento intenso em milhares de linhas em um DataSet, então eu escolhi para escrever um pedaço de código que em cache os índices de coluna pelo nome. Em seguida, o código de circuito I utilizados os índices em cache. Isso deu um aumento de desempenho razoável sobre o uso do nome da coluna diretamente.

Sua milhagem pode variar, é claro. Minha situação foi uma vez inventado e caso incomum, mas nesse caso ele funcionou muito bem.

A minha opinião é que você só deve mudar para índices se perfilado seu código e ele mostrou como o gargalo. Eu não acho que isso vai acontecer.

material Naming é bom, faz nosso cérebro limitado compreender os problemas e construir ligações mais fáceis. É por isso que são dadas nomes como Fred, Martin, Jamie, em vez de humana [189333847], Human [138924342] e Humano [239333546].

Se você se decidir para ofuscar o banco de dados, alterando os nomes das colunas no futuro, você poderia apelidar essas colunas na sua consulta para manter o código indexador funcional. Sugiro indexação pelo nome.

Vá com o nome, você obter melhores mensagens de erro:)

Eu optar por cordas para facilitar a leitura e manutenção. Eu uso contstants cordas para definir os valores dos nomes das colunas. Ex:

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

Então eu posso fazer referência a ela mais tarde como esta:

row[ExampleDataColumns.ID]

Use nomes de coluna para DataRow Da mesma forma que um RDBMS não vai ganhar velocidade, exigindo que os programadores para especificar o índice da coluna em SQL. Mas talvez você possa imitar a forma como um RDBMS operar quando você emitir uma instrução SELECT, dentro de um motor RDBMS que consultar o índice da coluna / deslocamento de colunas especificadas na cláusula SELECT antes de atravessar as linhas, para que ele possa operar mais rápido.

Se você realmente quiser ganhar velocidade, não fazer isso da maneira const / enum (ordem da coluna pode mudar em seu banco de dados ou camada ORM). Fazê-lo como TcKs sugeriu (antes do laço real):

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

para mim, eu estou usando a reflexão (não tenho certeza que é a maneira correta para citar o que eu faço) para obter o columnnameColumn da mesa

não "codificar" é melhor

  int price = (int)dr[DatableVar.PriceColumn];
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top