У меня есть отношения мастер-детали между 2 классами.Мастер-класс будет содержать список многих деталей.В настоящее время я использую
public class Master: cloneable<T>
{
//other properties here...
private List<detailClass> details
public List<detailClass> Details
{
get { return details; }
}
}
внутри мастер-класса.При сохранении этого класса мне нужно использовать таблицу данных для списка деталей, прежде чем передать его в sp.(поскольку мы используем параметры табличных значений в sql2008).причина использования tvp заключается в том, что 1 мастер может содержать более 10 тыс. деталей, а tvp - очень эффективный способ очень быстрой передачи всей этой информации в БД.
Qs: Когда я преобразую список в таблицу данныхдля вставки БД используется двойная память для тех же данных.Есть ли лучший способ сохранить детали в 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;
}
}
}