2010-01-28 3 views
11

ein paar Tutorials Nach und so konnte ich eine Sammlung Klasse erfolgreich erstellen, die die Funktionalität erbt benötigt, um eine Datentabelle zu schaffen, die weitergegeben werden können Die gespeicherte Prozedur eines Sql-Servers als Tabellenwertparameter. Alles scheint gut zu funktionieren; Ich kann alle Zeilen hinzufügen und es sieht schön aus. Bei näherer Betrachtung bemerke ich jedoch, dass beim Hinzufügen einer neuen Zeile die Daten für alle vorherigen Zeilen mit dem Wert für die neue Zeile überschrieben werden. Wenn ich also eine Reihe mit einem String-Wert von „foo“ und I fügt eine zweite Zeile mit dem Wert „bar“, wird die zweite Reihe eingefügt werden (eine Datentabelle mit zwei Reihen zu machen), aber beide Reihen haben den Wert „bar ". Kann jemand sehen, warum das wäre? Hier ist ein Teil des Codes, der funktioniert, aber etwas vereinfacht wurde (die Klasse Tag wurde zur einfacheren Erklärung reduziert).Warum einen neuen Wert wirkt sich das Hinzufügen in der Liste vorherigen Werte zur Liste <> überschreiben <>

Das Folgende ist die Sammlung Klasse:

using System; 
using System.Collections.Generic; 
using System.Data; 
using System.Linq; 
using System.Web; 
using Microsoft.SqlServer.Server; 

namespace TagTableBuilder 
{ 
public class TagCollection : List<Tag>, IEnumerable<SqlDataRecord> 
{ 
    IEnumerator<SqlDataRecord> IEnumerable<SqlDataRecord>.GetEnumerator() 
    { 
     var sdr = new SqlDataRecord(
      new SqlMetaData("Tag", SqlDbType.NVarChar) 
      ); 

     foreach (Tag t in this) 
     { 
      sdr.SetSqlString(0, t.tagName); 

      yield return sdr; 
     } 
    } 
} 

public class Tag 
{ 
    public string tagName { get; set; } 
} 
} 

Diese genannt werden wie folgt:

//Create instance of collection 
TagCollection tags = new TagCollection(); 

//Create instance of object 
Tag _tag = new Tag(); 

foreach (string t in tagList) 
{ 
    //Add value to class propety 
    _tag.tagName = t; 
    //Add class to collection, this is where all previously added rows are overwritten 
    tags.Add(_tag); 
} 
+0

Ja bitte ich werde das beheben, danke! –

Antwort

25

Sie verwenden die gleiche Instanz des Tag Objekt innerhalb der Schleife, so dass jedes Update Der TagName bezieht sich auf dieselbe Referenz. Verschieben Sie die Deklaration in der Schleife bei jedem Durchlauf der Schleife ein neues Objekt zu erhalten:

foreach (string t in tagList) 
{ 
    Tag _tag = new Tag(); 

    //Add value to class propety 
    _tag.tagName = t; 
    //Add class to collection, this is where all previously added rows are overwritten 
    tags.Add(_tag); 
} 

Beachten Sie auch, dass ich die letzte Zeile aktualisiert _tag hinzufügen statt mTag wie ich das irgendwo definiert nicht sehen.

2

In der Schleife, in der Sie die Tags zur Sammlung hinzufügen, verwenden Sie die gleiche Objektinstanz von Tag. Im Wesentlichen setzen Sie den Namen eines Tags auf den ersten Wert in tagList und fügen ihn der Auflistung hinzu. Dann ändern Sie den Namen desselben Tags in den zweiten Wert in tagList und fügen ihn erneut zur Sammlung hinzu.

Ihre Sammlung von Tags enthält mehrere Verweise auf den gleichen Tag Objekt! Instanziieren Sie _tag innerhalb der for-Schleife, bevor Sie den Namen des Tags festlegen und zur Sammlung hinzufügen.

Verwandte Themen