ですlinq to sql-変更ADO.NET データセットテーブルアダプターの更新を行?
-
23-08-2019 - |
質問
ここでは、関係する技術の仕事をしてい:
- Devartのドットの接続のためにOracleをLinq to Sql Oracle).
- 強く型付けされたADO.NET データセット
- は、Oracleデータベースです。
こちらの挑戦:
- 私のレガシーコードを提出データベース更新ADO.NET データセットやテーブルアダプタ
- たいと思い始まりに変換するコードへのLinq to Sqlしてしまいましたが、まず私か片をコードの解約率およびリスクです。
ここでの私のスキーマ:
親テーブル
- Parent.Id
- Parent.名称
子テーブル
- 子供です。Id
- 子供です。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->子供です。ParentId(M:N)]
ここでの私の質問:
- したいラップ全体のコードブロック る取引はない。
- したらよいです。を考える:
- に向かって調べましたが更新され、親テーブル Linq to Sqlの SubmitChanges方法...
- やりたいコミットする 更に、子テーブル ADO.NET データセット テーブルアダプター.
ここでは二つの面白い脚注:
- この全体のもの 作品 に 逆になります。れてしまうことがありました を提出しの変更は、親テーブル データアダプター変更 の子テーブルとlinq to sql...その う.
って明示的に付けの取引にdataadapterがコンパイラを許さないのではないでしょうをはじめ全国から足で集めた個性の異なるタイプの取引はない。
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();
解決
なことはわかりませんオラクルについて取引...しかしdotnet側にスイスでもフェルデンクライスを制御する取引ます。必ず両方の技術を使用して接続インスタンス.
しな取引を通じての接続ではなく、ORMを用いて取引の対象範囲: http://msdn.microsoft.com/en-us/library/ms172152.aspx
他のヒント
同じ問題が発生し、次の 2 つのエラーが発生しました。
- 整合性制約違反 (ORA-02291)
- 「キーがデータベースで生成されていない場合、同じキーを持つエンティティを挿入できません」
問題は、子オブジェクトの ID 列が適切に設定されていないことでした。DotConnect LINQ が ID キーを想定していない場合、オブジェクトのプロパティがアドホックに設定されているように見え、更新が非順次になり、整合性違反が発生します。
修正は次のとおりです。
- LINQ は、子の主キーがエンティティ キーであり、自動生成されることを認識する必要があります。
- Oracle では、子オブジェクトの自動インクリメントキーを設定します。
まずシーケンスを作成します。
DROP SEQUENCE MyChild_SEQ; CREATE SEQUENCE MyChild_SEQ MINVALUE 1 MAXVALUE 999999999999999999999999999 START WITH 1 INCREMENT BY 1 CACHE 20;
次に OnInsert トリガーを作成します。
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
ストレージ モデルを変更して、新しい自動生成された主キーを組み込みます。
- dotConnect の EntityDeveloper で、LINQ ストレージ モデル (.LQML ファイル) を開きます。
- 子オブジェクトのエンティティ キーを「自動生成値」に設定し、自動同期を「OnInsert」に設定します。
- ストレージ モデルを保存し、Visual Studio でソリューションをクリーンにして再構築します。
- 子の主キーを明示的に設定するコードをすべて削除します。
- LINQ はこれを自動インクリメントとして暗黙的に認識し、トリガーによって作成された ID を取得します。
コードでは、子オブジェクトを作成した後、次のようにそれを親にアタッチします。
ChildType newChild = new ChildType(); DataContext.InsertOnSubmit(newChild); Parent.Child = newChild;
その他のリソースは次のとおりです。
- 増加する主キーを持つ行を挿入します
- カスケード シーケンス ORA でエンティティ コンテキストを保存する際の問題
- 自動インクリメント列のサポート (LinqConnect+Oracle)
乾杯!
のTransactionScopeクラスを使用します。
あなたは異なるデータベースを使用している場合は、あなたのDTC構成を確認する必要があります(または、彼らは別々のサーバ上に存在する)ことに注意してください。
所属していません StackOverflow