6

LINQtoSQLを使用して「insertinto...select」タイプのコマンドを実行できるかどうかを調べようとしています。特定のテーブルに複数の行を挿入する単一のSQLコマンドをデータベースに送信できるようにするLINQtoSQLコードのビット。

たとえば、LINQtoSQLで次のT-SQLステートメントをSQLServerデータベースに送信するにはどうすればよいですか。

INSERT INTO Table1 
SELECT Table2.column1 + 1 AS column1, Table2.column2 + 2 AS column2
WHERE Table2.column3 > 100

もちろん、この関数を使用してこれを実現することもできDataContext.ExecuteCommandますが、これは、で取得する自動トランザクション処理を利用せずにすぐに実行されますDataContext.SubmitChanges。これ以外にも一連のアップデートがあり、エラーが発生した場合にすべてロールバックしてほしい。

何か案は?

更新:実際のコードは次のとおりです。

        var bs_prep =
            from b in dc.T_EDR_FILEBODies
            join
            unpaid in dc.V_UNPAIDs
            on
                b.NUM_ADC.Substring(1, 9) equals unpaid.NOCONT
            join
            acordo in dc.T_ACORDOS_RECOM_APREs
            on
                Convert.ToInt32(b.NUM_ADC.Substring(1, 9)) equals acordo.ID_Contrato
            where
                b.ID_EDR == id_edr
                &&
                (
                    unpaid.NUM_INCUMPRIMENTOS <= max_unpaid_consec
                    &&
                    unpaid.TOTAL_NUM_INCUPRIMENTOS <= max_unpaid_nonconsec
                )
                ||
                (
                    acordo.Activo == true
                    &&
                    acordo.Data_Recomeco <= now
                )
            select new
                {
                    ID_EDR = id_edr_filt,
                    NUM_LINHA = b.NUM_LINHA,
                    CODREJ = b.CODREJ,
                    HDT = b.HDT,
                    IMPORT = b.IMPORT,
                    NIB_DEV = b.NIB_DEV,
                    NUM_ADC = b.NUM_ADC,
                    REF_DD_BC = b.REF_DD_BC,
                    REF_MOV = b.REF_MOV
                }
            ;


        dc.T_EDR_FILEBODies.InsertAllOnSubmit(
            bs_prep.Select(
                b => new T_EDR_FILEBODY{
                    CODREJ = b.CODREJ,
                    HDT = b.HDT,
                    ID_EDR = b.ID_EDR,
                    IMPORT = b.IMPORT,
                    NIB_DEV = b.NIB_DEV,
                    NUM_ADC = b.NUM_ADC,
                    NUM_LINHA = b.NUM_LINHA,
                    REF_DD_BC = b.REF_DD_BC,
                    REF_MOV = b.REF_MOV
                }
            )
        );

簡単な説明:T_EDR_FILEBODiesエンティティは、インポートするいくつかのテキストファイルの内容を基本的に格納するデータベーステーブルにマップされます。1つのレコードは、テキストファイルの1行に対応します。

私がやろうとしているのは、1つのファイルからレコードをコピーし、新しいファイルID(ID_EDR=id_edr_filt)を付けて、一部の行をフィルターで除外することにより、フィルター処理されたバージョンのファイルコンテンツを作成することです。LINQ to SQLエンティティは、データベーステーブルへの直接マッピングです。これまでのところ、データコンテキストにコードを追加していません。それらは主キーを持っています、さもなければ私はそれらに挿入をすることができません(私が主キーを取り除くならば私はその例外を取り除くことができるだろうどこかで読んだでしょう、しかしあなたが見ることができるように、それはそうではありません私の場合は動作します)。

実行すると、次の例外がスローされInsertAllOnSubmitます。

クエリでのエンティティタイプ「T_EDR_FILEBODY」の明示的な構築は許可されていません。

クエリ内にエンティティを明示的に作成するのは問題があることを理解していると思います。クエリによって返されるエンティティには変更の追跡機能があり、submitchangesが呼び出されると変更がデータベースに変換されます。しかし、クライアント側で作成されたエンティティの変更をデータベースにどのように変換できますか?しかし、これは本当に、LINQtoSQLを使用してINSERTINTO... SELECTタイプのコマンドを実行できないことを意味しますか?

4

1 に答える 1

1

使用できます

ctx.Table1.InsertAllOnSubmit(
    mySelectEnumeration.Select(x => new Table1DT { ... })
);
  • InsertAllOnSubmitLinq to SQL テーブルに多数のエントリを挿入します。
  • mySelectEnumeration挿入するアイテムを選択するクエリです。
  • Select(new Table1DT { ... })選択したクエリのデータ型をテーブルのデータ型に変換するために必要な変換です。

または、メソッドを使用しExecuteCommandてトランザクションを手動で管理することもできます。

using (var ctx = new DataClasses1DataContext()) {
    ctx.Connection.Open();
    using (ctx.Transaction = ctx.Connection.BeginTransaction()) {
        ctx.ExecuteCommand("sqlcommand");
        ctx.Transaction.Commit();
    }
}

またはトランザクション スコープを使用します。

using (var ctx = new DataClasses1DataContext()) {
    using (var scope = new TransactionScope()) {
        ctx.ExecuteCommand("sqlcommand");
        scope.Complete();
    }
}
于 2010-03-02T16:17:07.200 に答える