私は1つのテーブル(asset_type)にレコードを作成し、2番目のテーブル(アセット)の外部キーを使ってレコードを参照する状況があります。この状況では、これらの挿入は両方とも同じTransactionScope内で発生します。 EFコードを使用する挿入が、最初にTransactionScope内で失敗するのはなぜですか?
生たDbConnectionを使用して
、挿入が成功している:conn.ConnectionString = "host=localhost;port=5432;database=test_client_alpha;user id=tcauser;password=tcapw";
using (var trans = new TransactionScope())
{
conn.Open();
conn.EnlistTransaction(Transaction.Current);
var cmd = conn.CreateCommand();
cmd.CommandText = "INSERT INTO overview.asset_type (name) VALUES('Unknown') RETURNING id";
var assetTypeId = (int)cmd.ExecuteScalar();
cmd.CommandText = string.Format("INSERT INTO overview.asset "
+ "(asset_type_id, client_id, is_active, is_gps_active, is_virtual, default_lon, default_lat) "
+ "VALUES ({0}, 'mid', TRUE, TRUE, FALSE, 0, 0) "
+ "RETURNING id ", assetTypeId);
var assetId = (int)cmd.ExecuteScalar();
trans.Complete();
}
しかし、私はDbContextクラスの使用に切り替える場合は、(資産への)2番目の挿入が外部キー制約違反で失敗したかのように最初の挿入(asset_typeへ)は発生しませんでした。
conn.ConnectionString = "host=localhost;port=5432;database=test_client_alpha;user id=tcauser;password=tcapw";
using (var trans = new TransactionScope())
{
using (var context = new TestContext(conn, false))
{
var assetTypeId = context.Database
.SqlQuery<int>("INSERT INTO overview.asset_type (name) VALUES('Unknown') RETURNING id")
.Single();
var assetId = context.Database
.SqlQuery<int>(string.Format("INSERT INTO overview.asset "
+ "(asset_type_id, client_id, is_active, is_gps_active, is_virtual, default_lon, default_lat) "
+ "VALUES ({0}, 'mid', TRUE, TRUE, FALSE, 0, 0) "
+ "RETURNING id ", assetTypeId))
.Single();
trans.Complete();
}
}
DbContextの例は正常に実行されます。
IsolationLevelの設定(ReadCommitted、ReadUncommitted)で再生しようとしましたが、成功しませんでした。
私はこの例ではTransactionScopeは必要ないことを認識しています。これは、複数のデータベースとのやりとりや分散トランザクションが必要な、より大きなコードの一部です。
私のデータベースはPostgreSQLであり、DevArtのdotConnect .NETドライバを使用しています。
誰かがDbContextの例が機能しない理由についての洞察はありますか?
DbContextの生のSQLメソッドを実際に使ったことはありませんでしたが、READ操作(クエリ)でのみ 'SqlQuery'でなく、INSERT、UPDATE、DELETEのようにDMLで' ExecuteSqlCommand'ですか?しかし、私はあなたが例外を取得しないことに驚いています。 – Slauma
SQL ServerとSQLClientをプロバイダとして使用して、同様のコードをテストしました(ただし、同じロジック:table1にrow1を挿入し、row2をrow1にFKでtable2に挿入)。 'TransactionScope'の有無にかかわらず動作しました。この問題は、PostgreSQLまたはdotConnectドライバと関係している可能性があります。 – Slauma