2

私は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;
        }
    }
}
4

1 に答える 1

1

次の2つの方法のいずれかを使用して、結果をテーブル値パラメーターにストリーミングできます。

  • IEnumerable<SqlDataRecord>-実装(またはさらに簡単なLINQ)で使用して、ストリーミングソリューションを作成できますyield returnIEnumerable<SqlDataRecord>
  • DbDataReader実装-リストへの参照を取得し、リーダーが列挙されるときに適切な変換を提供する実装を作成できます。

これらのいずれかを使用すると、基本的に、リストからアイテムを取得し、その結果をテーブル値パラメーターとしてストリーミングされるように変換する実装を作成できます。このように、アプリケーションで2番目のリストを再実体化する必要はなく、必要に応じて最初のリストで変換を実行できます。

詳細については、MSDNの「SQLServer 2008のテーブル値パラメーター」というタイトルのセクション、具体的には「SqlParameterの例の構成」および「DataReaderを使用した行のストリーミング」セクションを参照してください。

于 2010-08-23T15:26:20.850 に答える