c# - tipo - table value parameters
¿Por qué añadir un nuevo valor a la lista<> sobrescribe los valores anteriores en la lista<> (2)
En el bucle donde agrega las etiquetas a la colección, está usando la misma instancia de objeto de Tag. Básicamente, está configurando el nombre de una Etiqueta para el primer valor en tagList y agregándolo a la colección, luego está cambiando el nombre de esa misma Etiqueta por el segundo valor en tagList y lo vuelve a agregar a la colección.
¡Su colección de etiquetas contiene varias referencias al mismo objeto de etiqueta! Cree una instancia de _tag dentro del bucle for cada vez antes de configurar el nombre de la etiqueta y agregarla a la colección.
Después de algunos tutoriales, pude crear con éxito una clase de colección que hereda la funcionalidad necesaria para crear una DataTable que se puede pasar al procedimiento almacenado de un servidor Sql como un parámetro de valor de tabla. Todo parece estar funcionando bien; Puedo agregar todas las filas y se ve hermosa. Sin embargo, tras una inspección más cercana noté que cuando agrego una nueva fila, los datos de todas las filas anteriores se sobrescriben con el valor de la nueva fila. Entonces, si tengo una fila con un valor de cadena de "foo" y agrego una segunda fila con el valor "barra", se insertará la segunda fila (haciendo una DataTable con dos filas) pero ambas filas tendrán el valor "bar" ". ¿Alguien puede ver por qué sería esto? Aquí hay algunos códigos, que funcionan pero se han simplificado un poco (la clase Tag se ha reducido para facilitar la explicación).
La siguiente es la clase de la Colección:
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; }
}
}
Estos se llaman de la siguiente manera:
//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);
}
Está utilizando la misma instancia del objeto Tag
dentro del bucle, por lo que cada actualización de tagName tiene la misma referencia. Mueva la declaración dentro del ciclo para obtener un objeto nuevo en cada pasada del ciclo:
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);
}
También observe que actualicé la última línea para agregar _tag
lugar de mTag
ya que no veo esto definido en ningún lado.