Вот соответствующие технологии, с которыми я работаю:
- Devart dot Connect для Oracle (для облегчения Linq-to-Sql для Oracle).
- Сильно типизированные наборы данных ADO.NET.
- База данных Oracle.
Вот вызов:
- Мой устаревший код отправляет обновления базы данных с наборами данных ADO.NET и адаптерами таблиц.
- Я бы хотел начать преобразование этого кода в Linq-to-Sql, но я бы хотел сделать это по частям, чтобы минимизировать отток и риск кода.
Вот мое подтверждение концепции схемы:
Родительская таблица
Детский стол
- Child.Id
- Child.ParentId
- Child.Name
Вот мое доказательство концепции кодового блока:
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-to-Sql SubmitChanges ...
- И я хочу совершить
обновление таблицы Child с
Набор данных ADO.NET настольный адаптер .
Вот две интересные сноски:
- Все это работает в
задний ход. То есть если бы я хотел
отправить изменения в родительскую таблицу
с адаптером данных и изменениями
дочерний стол с linq-to-sql ...
что будет работать .
Я пытался явно присоединить транзакцию к адаптеру данных, но компилятор не разрешил это, потому что это другой тип транзакции.
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();