我在两个类之间有一个主从关系。大师班将包含许多细节的列表。目前我正在使用
public class Master: cloneable<T>
{
//other properties here...
private List<detailClass> details
public List<detailClass> Details
{
get { return details; }
}
}
大师班里面。在保存此类时,我需要在将详细信息列表传递给 sp 之前使用数据表。(因为我们在 sql2008 中使用表值参数)。使用 tvp 的原因是 1 个 master 可以包含超过 10k 的详细信息,并且 tvp 是一种非常有效的方式,可以非常快速地将所有这些信息转储到数据库中。
问:当我将列表转换为数据表以进行数据库插入时,相同数据的内存使用量会增加一倍。除了直接使用数据表之外,还有更好的方法将详细信息保存在 master 中吗?
问:我的下一个选项是尝试使用列表详细信息,并执行 datatable.ImportRow(row)。但我不知道,如何在没有定义任何列的情况下将数据添加到行中。我也不知道任何外部对象如何访问此类列表中的各个详细信息字段。
按照casperOne 的回答,我使用了该IEnumerable<SqldataRecord>
方法,并且能够通过流式传输插入数据,而无需在内存中创建额外的数据表。为了帮助其他寻找类似解决方案的人,我在下面发布代码。
public class DetailCollection: List<Detail>, IEnumerable<SqlDataRecord>
{
IEnumerator<SqlDataRecord> IEnumerable<SqlDataRecord>.GetEnumerator()
{
// mapping the properties of the Detail object to the
// user defined table type in sql
SqlMetaData[] metaDataArray = new SqlMetaData[4];
//-1 indicates varchar(max) sql data type
metaDataArray[0] = new SqlMetaData("Col1", SqlDbType.VarChar, -1);
metaDataArray[1] = new SqlMetaData("Col2", SqlDbType.TinyInt);
metaDataArray[2] = new SqlMetaData("Col3", SqlDbType.VarChar,100);
metaDataArray[3] = new SqlMetaData("Col4", SqlDbType.Int);
SqlDataRecord sdr = new SqlDataRecord(metaDataArray);
foreach (Detail detailRecord in this)
{
sdr.SetValue(0, detailRecord.Property1);
sdr.SetValue(1, Convert.ToByte(detailRecord.Property2));
sdr.SetValue(2, detailRecord.Property3);
sdr.SetValue(3, detailRecord.Property4);
yield return sdr;
}
}
}