Linq to sql 能否在单个事务中包含linq到sql的更改和ADO.NET数据集表适配器更新?
以下是我正在使用的相关技术:Linq to sql 能否在单个事务中包含linq到sql的更改和ADO.NET数据集表适配器更新?,linq-to-sql,ado.net,transactions,dataset,devart,Linq To Sql,Ado.net,Transactions,Dataset,Devart,以下是我正在使用的相关技术: Devart的用于Oracle的dot Connect(促进用于Oracle的Linq到Sql) 强类型ADO.NET数据集 甲骨文数据库 以下是挑战: 我的旧代码使用ADO.NET数据集和表适配器提交数据库更新 我希望开始将代码转换为Linq到Sql,但我希望零碎地将代码转换和风险降至最低 以下是我的概念证明模式: 父表 父.Id 父项名称 子表 儿童身份证 Child.ParentId 孩子的名字 以下是我的概念验证代码块: using Sys
- Devart的用于Oracle的dot Connect(促进用于Oracle的Linq到Sql)
- 强类型ADO.NET数据集
- 甲骨文数据库
- 我的旧代码使用ADO.NET数据集和表适配器提交数据库更新
- 我希望开始将代码转换为Linq到Sql,但我希望零碎地将代码转换和风险降至最低
以下是我的概念证明模式: 父表
- 父.Id
- 父项名称
- 儿童身份证
- Child.ParentId
- 孩子的名字
using System;
using System.Data.Common;
using DevArtTry1.DataSet1TableAdapters;
namespace DevArtTry1
{
class Program
{
static void Main(string[] args)
{
using (DataContext1 dc = new DataContext1())
{
dc.Connection.Open();
using (DbTransaction transaction = dc.Connection.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
{
dc.Transaction = transaction;
Parent parent = new Parent();
parent.Id = 1;
parent.Name = "Parent 1";
dc.Parents.InsertOnSubmit(parent);
dc.SubmitChanges(); // By virtue of the Parent.Id -> Child.ParentId (M:N) foreign key, this statement will impose a write lock on the child table.
DataSet1.CHILDDataTable dt = new DataSet1.CHILDDataTable();
DataSet1.CHILDRow row = dt.NewCHILDRow();
row.ID = 1;
row.PARENTID = 1;
row.NAME = "Child 1";
dt.AddCHILDRow(row);
CHILDTableAdapter cta = new CHILDTableAdapter();
// cta.Transaction = transaction; Not allowed because you can't convert source type 'System.Data.Common.DbTransaction to target type 'System.Data.OracleClient.OracleTransaction.
cta.Update(dt); // The thread will encounter a deadlock here, waiting for a write lock on the Child table.
transaction.Commit();
}
}
Console.WriteLine("Successfully inserted parent and child rows.");
Console.ReadLine();
}
}
}
- 如上面的注释所示,线程将在子数据适配器的更新调用上无限期地停止,因为它将无限期地等待子表上的写锁。[注意外键关系:Parent.Id->Child.ParentId(M:N)]
- 我想包装整个代码块 在交易中
- 我能做这个吗?考虑到:
- 我想使用提交父表的更新 Linq到Sql的提交更改方法
- 我想做出一个承诺 使用 ADO.NET数据集表适配器
以下是两个有趣的脚注:
CHILDTableAdapter cta = new CHILDTableAdapter();
cta.Transaction = transaction; // Not allowed because you can't convert source type 'System.Data.Common.DbTransaction' to target type 'System.Data.OracleClient.OracleTransaction'.
cta.Update(dt);
transaction.Commit();
我对Oracle的交易一无所知。。。但在dotnet方面,您应该可以自己控制交易。确保两种技术使用相同的连接实例
当我们通过连接而不是ORM控制事务时,我们使用事务作用域:使用TransactionScope类
请注意,如果您使用不同的数据库(或它们位于不同的服务器上),则需要检查DTC配置。我遇到了相同的问题,遇到以下两个错误:
- 完整性约束冲突(ORA-02291)
- “如果密钥不是数据库生成的,则无法插入具有相同密钥的实体”
- LINQ需要知道子级的主键是一个实体键,并且是自动生成的
- 在Oracle中,为子对象设置自动递增键
- 首先创建一个序列:
- 接下来创建OnInsert触发器:
- 修改存储模型以合并新的自动生成主键:
- 在EntityDeveloper for dotConnect中,打开LINQ存储模型(.LQML文件)
- 将子对象的实体键设置为“自动生成值”,并将自动同步设置为“OnInsert”
- 保存存储模型,然后在Visual Studio中清理并重新生成解决方案
- 删除显式设置子项主键的所有代码。
- LINQ将隐式地将其识别为自动递增,并检索触发器创建的ID
- 在代码中,创建子对象后,将其附着到父对象,如下所示:
- 插入主键递增的行
- 用级联序列保存实体上下文的问题
- 自动增量列支持(LinqConnect+Oracle)
DROP SEQUENCE MyChild_SEQ;
CREATE SEQUENCE MyChild_SEQ
MINVALUE 1
MAXVALUE 999999999999999999999999999
START WITH 1
INCREMENT BY 1
CACHE 20;
CREATE OR REPLACE TRIGGER MyChild_AUTOINC
BEFORE INSERT
ON MyChildObject
FOR EACH ROW
BEGIN
SELECT MyChild_SEQ.nextval
INTO :NEW.MyChild_ID
FROM dual;
END MyChild_AUTOINC ;
ALTER TRIGGER MyChild_AUTOINC ENABLE
ChildType newChild = new ChildType();
DataContext.InsertOnSubmit(newChild);
Parent.Child = newChild;