Frage

Wenn die Werte von einem DataRow Abrufen ist es besser, die Spaltennamen oder Spaltenindex zu benutzen?

Der Spaltenname ist besser lesbar und leichter zu pflegen:

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

Während Spaltenindex ist nur schneller (glaube ich):

int price = (int)dr[3];

Würde Spaltennamen brechen zu verwenden, wenn Sie sich entscheiden, um die Datenbank zu verschleiern?

War es hilfreich?

Lösung

Ich ziehe es im Allgemeinen der Lesbarkeit und das Verständnis über Geschwindigkeit. Gehen Sie mit dem Namen. Sie könnte (sollte) String-Konstanten verwenden, die in einem Ort aktualisiert werden können, wenn Sie sich entscheiden, Datenbank Spaltennamen zu ändern.

Andere Tipps

Zugriff auf Spalten / Zeilenwerte über Spaltennamen ist besser für den Menschen das Lesen und für die Vorwärtskompatibilität (wenn in Zukunft jemand Reihenfolge oder Anzahl der Spalten ändern).

Accissing Spalten / Zeilenwerte über Spaltenindizes ist besser für die Leistung.

Also, wenn Sie einen Wert in einer / zwei ändern wollen / ..... Reihen, sind die Spaltennamen in Ordnung. Aber wenn Sie einen Wert in Tausende von Zeilen ändern möchten, sollten Sie den Index der Spalte von Spaltennamen berechnet verwenden:

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

Komplett agress mit anderen wieder. gehen, um die Lesbarkeit und Wartbarkeit über Geschwindigkeit. Ich hatte jedoch eine generische Methode, die genannten Spalten als Parameter in get benötigt, um übergeben, so dass es sinnvoll war, herauszufinden, was dort Spaltenindizes waren.

Im Benchmarking unter Spaltenindex zeigte eine große Verbesserung also, wenn dies zu einem Engpass-Bereich oder eine Leistung kritische Teil des Codes kann es sinnvoll sein.

Die Ausgabe aus dem Code unten:

515ms mit Column

1031ms mit Spaltennamen

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

Ich würde denken, der Spaltenname ist der beste Weg zu gehen. Es ist einfacher, zu bestimmen, was Sie ziehen und die Spaltenreihenfolge wird durch die select-Anweisung bestimmt, die irgendwann auf der Straße ändern könnte. Sie könnten die Spaltennamen ändern argumentieren könnten, aber ich würde denken, dies wäre viel weniger wahrscheinlich.

EDIT:

Eigentlich, wenn Sie wirklich verbogen waren Spaltenindizes auf verwenden Sie Konstanten des Spaltenindizes schaffen könnten und die Konstante, die den Namen des Spalts zu nennen. Also:

PRIMARY_KEY_COLUMN_NAME_INDEX = 0

Das wäre zumindest macht es lesbar ist.

Es hängt davon ab, was Sie brauchen. In meinem Fall hatte ich eine Situation, in der Geschwindigkeit von größter Bedeutung war, als ich auf Tausende von Zeilen in einem DataSet intensive Verarbeitung ausführen, so wählte ich ein Stück Code zu schreiben, der die Spaltenindizes nach Namen zwischengespeichert. Dann wird in der Schleife Code benutzte ich die zwischengespeicherten Indizes. Dies ergab eine angemessene Leistungssteigerung gegenüber der Spaltennamen direkt verwendet wird.

die Leistung kann variieren, natürlich. Meine Situation war ein ziemlich gekünstelt und ungewöhnlicher Fall, aber in diesem Fall war es ziemlich gut.

Meine Meinung ist, dass Sie nur auf Indizes wechseln sollten, wenn Sie Ihren Code profiliert und es als Engpass zeigte. Ich glaube nicht, das wird passieren.

Naming Zeug ist gut, es macht unser begrenztes Gehirn Probleme verstehen und bauen Links einfacher. Deshalb haben wir Namen wie Fred gegeben, Martin, Jamie, anstatt Menschen [189333847] Mensch [138924342] und Mensch [239333546].

Wenn Sie haben Sie sich entschieden, die Datenbank zu verschleiern durch Spaltennamen in der Zukunft zu ändern, können Sie diese Spalten in Ihrer Abfrage alias könnten funktionalen den Indexer Code zu halten. Ich schlage vor, die Indizierung mit Namen.

Gehen Sie mit dem Namen, erhalten Sie bessere Fehlermeldungen:)

Ich entscheide mich für Streicher für gute Lesbarkeit und Wartbarkeit. Ich benutze String contstants die Werte der Spaltennamen zu definieren. Ex:

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

Dann kann ich es später wie folgt verweisen:

row[ExampleDataColumns.ID]

Spaltennamen für DataRow aus dem gleichen Grund verwenden, die ein RDBMS nicht an Geschwindigkeit gewinnen von Programmierern erfordert den Spaltenindex in SQL angeben. Aber man kann vielleicht die Art und Weise imitieren ein RDBMS arbeiten, wenn Sie eine SELECT-Anweisung ausführen, in einer RDBMS-Engine abfragen es den Spaltenindex / Offset von Spalten in SELECT-Klausel angegeben, bevor er die Zeilen durchlaufen, so dass es schneller arbeiten.

Wenn Sie wirklich an Geschwindigkeit gewinnen möchten, nicht tun es die const / enum Weg (Spaltenreihenfolge kann auf Ihrer Datenbank oder ORM-Schicht ändern). Machen Sie es so TCKS vorgeschlagen (vor der eigentlichen Schleife):

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

für mich, ich bin mit Reflexion (nicht sicher, es ist der richtige Weg zu nennen, was ich tue), um die columnnameColumn vom Tisch zu bekommen

Nein "Hardcoding" ist besser

  int price = (int)dr[DatableVar.PriceColumn];
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top