Refresh list item c #

1

I am filling an object of type Celda

public class Celda
{
    [DataMember]
    public int celda_id { get; set; }
    [DataMember]
    public string celda_codigo_empresa { get; set; }
    [DataMember]
    public string celda_modulo_codigo { get; set; }
    [DataMember]
    public int celda_orden { get; set; }
    [DataMember]
    public string celda_categoria_nombre { get; set; }
    [DataMember]
    public string celda_categoria_codigo { get; set; }
    [DataMember]
    public string indicador_nombre { get; set; }
    [DataMember]
    public string indicador_codigo { get; set; }
    [DataMember]
    public string indicador_tipo { get; set; }
    [DataMember]
    public string indicador_descripcion { get; set; }
    [DataMember]
    public List<CeldaKeyVal> valores_celdas { get; set; }
}

Containing a List of Object Cells type KeyVal

public class CeldaKeyVal
{
    [DataMember]
    public string celda_key_codigo { get; set; }
    [DataMember]
    public string celda_key_valor { get; set; }
}

Finally this would be like that List<Celda> celdas = new List<Celda>();

It happens that for a Celda there may be a list of CeldaKeyVal and unfortunately I do not have access to modify the Stored Procedure that brings me this data, I receive something like this:

CeldaId   CeldaKeyCodigo             CeldaKeyValue
1         Cod1                       Hola
1         Cod2                       Prueba
1         Cod3                       Test
2         C0d1                       Hola2

I go through the results like this:

List<CeldaKeyVal> listaCeldaKey = new List<CeldaKeyVal>();
foreach(DataRow dr in dtCelda.Rows) 
{

    bool existe = celdas.Any(item => item.celda_id == Convert.ToInt32(dr["CeldaId"]));
    if (existe) {
        Celda celda_existente = celdas.FirstOrDefault(cus => cus.celda_id == Convert.ToInt32(dr["CeldaId"]));
        CeldaKeyVal celda_key_val = new CeldaKeyVal();
        celda_key_val.celda_key_codigo = Convert.ToString(dr["CeldaKeyCodigo"]);
        celda_key_val.celda_key_valor = Convert.ToString(dr["CeldaKeyValue"]);
        listaCeldaKey.Add(celda_key_val);
        celdas.First(d => d.celda_id == Convert.ToInt32(dr["CeldaId"])).valores_celdas = listaCeldaKey;
        //celda_existente.valores_celdas = listaCeldaKey;
    } else {
        listaCeldaKey.Clear();
        Celda celda = new Celda();
        celda.celda_id = Convert.ToInt32(dr["CeldaId"]);
        celda.celda_codigo_empresa = Convert.ToString(dr["CeldaEmpresaCodigo"]);
        celda.celda_modulo_codigo = Convert.ToString(dr["CeldaModuloCodigo"]);
        celda.celda_orden = Convert.ToInt32(dr["CeldaOrden"]);
        celda.celda_categoria_nombre = Convert.ToString(dr["CeldaCategoriaNombre"]);
        celda.celda_categoria_codigo = Convert.ToString(dr["CeldaCategoriaCodigo"]);
        celda.indicador_nombre = Convert.ToString(dr["CeldaIndicadorNombre"]);
        celda.indicador_codigo = Convert.ToString(dr["CeldaIndicadorCodigo"]);
        celda.indicador_tipo = Convert.ToString(dr["CeldaIndicadorTipoCodigo"]);
        celda.indicador_descripcion = Convert.ToString(dr["CeldaIndicadorDescripcion"]);
        CeldaKeyVal celda_key_val = new CeldaKeyVal();
        celda_key_val.celda_key_codigo = Convert.ToString(dr["CeldaKeyCodigo"]);
        celda_key_val.celda_key_valor = Convert.ToString(dr["CeldaKeyValue"]);
        listaCeldaKey.Add(celda_key_val);
        celda.valores_celdas = listaCeldaKey;
        celdas.Add(celda);
    }

}

If they realize I identify if the item I am traveling with exists, I compare it by its Id . This works because it identifies which exists ... If it exists, I get the existing one and I modify its value cell_values that is my List<CeldaKeyValue> , however this does not work for me, once it exits and I create a new cell (because it has other Id ) clean listaCeldaKey to have a new list for the corresponding cell. However always keep the first one, it is as if I did not modify the list, and doing debug with interruption points I realized that when executing listaCeldaKey.Clear(); all the values that I saved inside my Celda.valores_celda are lost ... that is the error that I have, which according to me should not happen as I already assign them to a certain value of my Class.

    
asked by sioesi 26.10.2016 в 20:14
source

1 answer

1

I think the problem is a misunderstanding with the following line:

celdas.First(d => d.celda_id == Convert.ToInt32(dr["CeldaId"])).valores_celdas = listaCeldaKey;

It seems that you are under the impression that you are copying the content from the list listaCeldaKey to valores_celdas , and that from that moment listaCeldaKey and valores_celdas are 2 different lists . But this is not the case.

Rather, you are simply copying the reference from the list listaCeldaKey to valores_celdas . So any action you take on listaCeldaKey from that moment, including listaCeldaKey.Clear() , will affect both. Because, in effect, both references point to the same instance of the list.

One solution is to replace

listaCeldaKey.Clear();

... with ...

listaCeldaKey = new List<CeldaKeyVal>();

... to make sure you're manipulating a separate instance from that moment.

Edit: A better alternative

Personally, I would modify the code in this way to avoid having to handle an instance of the list outside the cycle.

foreach(DataRow dr in dtCelda.Rows) 
{
    bool existe = celdas.Any(item => item.celda_id == Convert.ToInt32(dr["CeldaId"]));
    if (existe) {
        Celda celda_existente = celdas.FirstOrDefault(cus => cus.celda_id == Convert.ToInt32(dr["CeldaId"]));

        CeldaKeyVal celda_key_val = new CeldaKeyVal();
        celda_key_val.celda_key_codigo = Convert.ToString(dr["CeldaKeyCodigo"]);
        celda_key_val.celda_key_valor = Convert.ToString(dr["CeldaKeyValue"]);

        celda_existente.valores_celdas.Add(celda_key_val);
    } else {
        Celda celda = new Celda();
        celda.celda_id = Convert.ToInt32(dr["CeldaId"]);
        celda.celda_codigo_empresa = Convert.ToString(dr["CeldaEmpresaCodigo"]);
        celda.celda_modulo_codigo = Convert.ToString(dr["CeldaModuloCodigo"]);
        celda.celda_orden = Convert.ToInt32(dr["CeldaOrden"]);
        celda.celda_categoria_nombre = Convert.ToString(dr["CeldaCategoriaNombre"]);
        celda.celda_categoria_codigo = Convert.ToString(dr["CeldaCategoriaCodigo"]);
        celda.indicador_nombre = Convert.ToString(dr["CeldaIndicadorNombre"]);
        celda.indicador_codigo = Convert.ToString(dr["CeldaIndicadorCodigo"]);
        celda.indicador_tipo = Convert.ToString(dr["CeldaIndicadorTipoCodigo"]);
        celda.indicador_descripcion = Convert.ToString(dr["CeldaIndicadorDescripcion"]);

        CeldaKeyVal celda_key_val = new CeldaKeyVal();
        celda_key_val.celda_key_codigo = Convert.ToString(dr["CeldaKeyCodigo"]);
        celda_key_val.celda_key_valor = Convert.ToString(dr["CeldaKeyValue"]);

        celda.valores_celdas = new List<CeldaKeyVal>();
        celda.valores_celdas.Add(celda_key_val);
        celdas.Add(celda);
    }

}
    
answered by 26.10.2016 / 20:28
source