私は2つのクラスの間にマスターとディテールの関係があります。マスタークラスには、多くの詳細のリストが含まれます。現在使用していた
public class Master: cloneable<T>
{
//other properties here...
private List<detailClass> details
public List<detailClass> Details
{
get { return details; }
}
}
マスタークラス内。このクラスを保存している間、spに渡す前に詳細リストのデータテーブルを使用する必要があります。(sql2008でテーブル値パラメーターを使用しているため)。tvpを使用する理由は、1つのマスターに10k以上の詳細を含めることができ、tvpはそのすべての情報をデータベースに非常に高速にダンプする非常に効率的な方法であるためです。
Qs:データベースを挿入するためにリストをデータテーブルに変換すると、同じデータに対して2倍のメモリ使用量が発生します。データテーブルを直接使用する以外に、マスターに詳細を保存するためのより良い方法はありますか?
Qs:次のオプションは、リストの詳細を使用して、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;
}
}
}