過去数日間に何度もコードを書き直したので、ここにはコードを含めません。これ以上気にする価値はないので、一般的な用語で問題を説明します。
C#で記述され、SQLサーバーデータベースに接続されたwinformsアプリケーションがあります。アプリケーションの特定の部分では、データベース内の多数のテーブルで最大10個のSQLコマンドを操作できますが、これは「オールオアナッシング」の状況であるため、1つのトランザクション内に含める必要があります。10個のコマンドのいずれかが失敗した場合、どのコマンドもコミットしないようにします。
複雑な要因は次のとおりです。
- 10個のsqlコマンドのそれぞれに複数のパラメーターがあります
- 一部のsqlcommandsはINSERTを使用し、後続のsqlcommandsの一部でサーバー生成IDを使用する必要があります。
- 一部のコマンドは同じデータを操作します。つまり、初期のコマンドはデータベースに新しいアイテムを挿入し、後のsqlcommandの1つは同じエントリを更新しようとします。
この問題は1週間のほとんどを費やしており、比較的進展が少ないように感じているので、助けていただければ幸いです。
編集:
sqlcommandsは元々異なるクラスなどにありましたが、それが問題になる可能性があるため、大幅な書き直しを行いました。一部のsqlcommandsは別の場所に書き込まれ、に返されますが、すべてのsqlcommandsは同じメソッド内にあります。主な方法。
現時点での問題は、最初のコマンド(INSERT)が実行されますが、最初のコマンドで作成されたデータベースエントリを参照しようとするため、2番目のコマンドでトランザクションが失敗することです。
また、ネットワーク上のMSDTCが他の問題を引き起こし、アプリケーションとADO.NETでこれを処理する必要があるため、TransactionScopeを使用できません。
編集(いくつかのコード)
トランザクション内の最初の2つのsqlコマンドは次のとおりです。
string connectionString = aSystem.ConnectionString;
using (SqlConnection linkToDB = new SqlConnection(connectionString))
{
linkToDB.Open();
using (SqlTransaction transaction = linkToDB.BeginTransaction())
{
try
{
//...Case...//
cCase c = new cCase();
c.CaseType = cboCaseType.Text;
c.Occupation = txtOccupation.Text;
c.DateInstructed = txtDateInst.Text;
c.Status = "Live";
SqlCommand sqlSaveCase = c.SaveSqlCom();
sqlSaveCase.Connection = linkToDB;
sqlSaveCase.Transaction = transaction;
c.SetCaseNo = sqlSaveCase.ExecuteNonQuery().ToString();
//...IP Link...//
string strIPID = cboIPAddress.SelectedValue.ToString();
SqlCommand sqlNewIPLink = cIPID.NewIPLinkSqlCom(strIPID,c.CaseNo,txtIPRef.Text);
sqlNewIPLink.Connection = linkToDB;
sqlNewIPLink.Transaction = transaction;
sqlNewIPLink.ExecuteNonQuery(); //...fails here...//
//...an additional 8 sql commands follow...//
問題
sqlSaveCaseコマンドはtblCasesに新しいケースを挿入しますが、2番目のコマンドsqlNewIPLinkが最初のコマンドによって作成されたIDを使用しようとすると、最初のコマンドから新しく作成されたケースが表示されないかのように外部キーエラーが生成されます。