2010-01-28 37 views
11

下面的几个教程和我能够成功创建一个集合类,它继承了创建一个DataTable所需的功能,可以传递给一个Sql Server的存储过程作为表值参数。一切似乎都运作良好;我可以添加所有的行,看起来很漂亮。但是,仔细观察后,我注意到当我添加一个新行时,所有前面的行的数据将被新行的值覆盖。因此,如果我有一个字符串值为“foo”的行,并添加第二行的值为“bar”,则会插入第二行(使两行为DataTable),但两行的值都将为“bar ”。任何人都可以看到为什么会这样?这里是一些代码,它的工作原理虽然简单一些(为了便于解释,Tag类已经缩小了)。为什么添加一个列表<>的新值覆盖列表中的以前的值<>

以下是集合类的:

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

这些被称为如下:

//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

是的,我应该解决这个问题,谢谢! – 2010-01-29 17:16:22

回答

25

您使用内循环Tag对象的同一实例,因此每次更新tagName是相同的参考。移动声明内循环,以获得在每个循环过程新对象:

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

还要注意,我更新了最后一行添加_tag而不是mTag,因为我没有看到这个在任何地方定义。

2

在将标记添加到集合的循环中,您使用的是Tag的同一对象实例。实质上,您将tag的名称设置为tagList中的第一个值并将其添加到集合中,然后将相同Tag的名称更改为tagList中的第二个值,然后再将其添加到集合中。

您的标签集合包含多个对同一个标签对象的引用!在设置标签名称并将其添加到集合之前,每次在for循环内部实例化_tag。

相关问题