我有一種情況,我創建一個表中的記錄(asset_type),並通過第二個表(資產)中的外鍵引用它。在這種情況下,這兩個插入都發生在同一個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類,第二個插入(成資產)失敗,一個違反外鍵約束,就好像第一次插入(進入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();
}
}
如果我刪除了TransactionScope,則DbContext示例正常執行。
我試着玩IsolationLevel設置(ReadCommitted,ReadUncommitted)沒有成功。
我意識到我不需要在這個例子中的TransactionScope。這是涉及與多個數據庫交互並需要分佈式事務的較大塊代碼的一部分。
我的數據庫是PostgreSQL,我使用的是DevArt的dotConnect .NET驅動程序。
有沒有人有任何洞察,爲什麼DbContext示例不起作用?
我從來沒有真正使用過DbContext的原始SQL方法,但對於DML(如INSERT,UPDATE,DELETE)而言,「SqlQuery」僅用於READ操作(查詢)和'ExecuteSqlCommand'嗎?但是,我很驚訝你沒有得到例外。 – Slauma
我測試了一個類似的代碼(但是相同的邏輯:在table1中插入row1,然後將table2中的row2插入到row1的FK中),SQL Server和SQLClient作爲提供程序。它既可以使用也可以不使用'TransactionScope'。這個問題可能與PostgreSQL或dotConnect驅動程序有關。 – Slauma