次のシナリオで EF (4.2) を使用したいと考えています。
- 既にデータベースが存在し (データベース優先のアプローチを選択したため)、それは SQL Anywhere DB です。
- 持続性を無視するビジネス オブジェクトを使用したいので、
DbContext
テンプレートを使用POCO
して EDM からクラスを生成します。 - 私のエンティティには、単純な継承階層が 1 つあります。抽象ベース エンティティと 2 つの具体的な派生エンティティです。
- データベースには、継承階層のタイプごとに 1 つのテーブルがあります (Table-Per-Type Strategy)。
- これら 3 つのテーブルにはそれぞれ主キー列 (
Id
、タイプ:integer
) があり、具体的なエンティティと基本エンティティの関連付けは、Id
両方のテーブルに同じものを含めることによって行われます (つまりId
、具体的なタイプ テーブルの主キー ( )同時にベーステーブルへの外部キーです;かなり一般的なアプローチだと思います)。
EDM アシスタントは自動的に認識しないため、デザイナーで継承を手動で定義する必要がありました。つまり、記述されたエンティティ間に継承の関連付けが必要です。
ここまで大きな問題はありませんでした。ここで、当面の問題について説明します。私が使用するデータベースには制限があります。Primarykey
値は、データベース関数を使用して、データベースによって生成される必要があります。before-insert-trigger
で定義されたでこの関数を呼び出したいですbase-table
。
値がデータベースによって生成されたことをエンティティ フレームワークに知らせるために、のプロパティのプロパティを設定しますStoreGeneratedPattern
(理解したように、これは、エンティティの新しいインスタンスを挿入した後に生成された値を取得するように EF に指示する方法です) )。Id
base-entity
Identity
派生エンティティの新しいインスタンスを作成し、それを対応する に追加しDbSet
てコンテキストDbContext
を呼び出すと、制約に違反していることを示す a がスローされます。DBのリクエストログを確認すると、ベースエンティティがベーステーブルに挿入されていることがわかりますが、派生テーブルに行を挿入すると、明らかに新しく生成されたのを使用していないため、上記のエラーが発生しますベース テーブルの新しいエントリ。SaveChanges
DbUpdateException
foreignkey
Id
それに対してデータベースレベルでできることはあまりないと思うので、質問は、EDMまたはDbContextを構成(または変更)してベース行を最初に挿入し、次に生成されたものを取得しId
て使用できるかどうかです。派生行の挿入。
この状況を回避するにはいくつかの方法があることを知っています (継承を使用しない、ストアド プロシージャを使用して新しい派生エンティティを挿入する、id 生成 db 関数を呼び出してエンティティにId
自分でプロパティを挿入して設定する) が、現時点では上記の動作が最も好ましいので、「プランB」を決定する前に何かを見落とさないようにしたい.
このトピックに関する提案は大歓迎です。よろしくお願いします。
トリガーのコードは次のとおりです。
ALTER TRIGGER "TRG_GENERATE_ID" before insert order 1 on
BASE_TABLE
referencing new as NewEntry
for each row
begin
declare NewID integer;
set NewID = F_GET_NEW_ID('BASE_TABLE', NewEntry.SOME_OTHER_ID);
set NewEntry.ID = NewID
end
関数 "F_GET_NEW_ID" がトリガーで呼び出され、ベース テーブルの新しいエントリの新しい ID が生成されます。これには 2 つのパラメーターがあります: "Tablename" -> 新しい ID を生成する必要があるテーブルの名前、およびデータベースのすべてのテーブルの standardcolumn の値を取る 2 番目のパラメーター (新しい ID を生成するために必要です) )。