gpt4 book ai didi

c# - 为什么使用 EF 代码的插入首先在 TransactionScope 中失败?

转载 作者:行者123 更新时间:2023-11-29 12:27:58 24 4
gpt4 key购买 nike

我有一种情况,我在一个表 (asset_type) 中创建一条记录,并通过第二个表 (asset) 中的外键引用它。在这种情况下,这两个插入都发生在同一个 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 类,第二次插入(插入 Assets )会因违反外键约束而失败,就好像第一次插入(插入 Assets 类型)没有发生一样:

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 示例不起作用?

最佳答案

Managing Connections and Transactions :

The Entity Framework opens connections only when required, for example to execute a query or to call SaveChanges, and then closes the connection when the operation is complete.

  • 调用以下任一方法打开连接:
  • 在 ObjectContext 上保存更改或刷新。
  • FirstOrDefault,或 ObjectQuery 上的 First。
  • 加载 EntityCollection。
  • 加载 EntityReference。
  • 任何语言集成查询 (LINQ) 方法或 ObjectQuery 查询生成器方法,例如 Where、OrderBy 或 Select。

然后它打开另一个连接,事务范围抛出异常。您必须设置 Distributed Transaction Coordinator (不能说它对 PostgreSQL 来说是真的还是假的)。

如果它是真实的,那么在设置 DTC 之后只需在范围内打开您的 conn 对象。

关于c# - 为什么使用 EF 代码的插入首先在 TransactionScope 中失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6711781/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com