Entity Framework:条件付き外部キー
-
03-07-2019 - |
質問
データベースに次のスキーマがあります:
- BillingReferences (ReferencingType tinyint 、ReferencingId tinyint 、ReferencedType tinyint 、ReferencedId tinyint 、IsActive ビット)-すべてのフィールド(IsActiveを除く)は一意のインデックスの一部です。
- BillingType (BillingTypeId tinyint 、名前 varchar(50))
ReferencingTypeおよびReferencedTypeは、BillingTypesの外部キーです。 BillingTypesには次の行が含まれます。
BillingTypeId |名前
1 |ラベル
2 |国
3 | PaymentProviders
4 | PaymentOptions
5 |銀行
ReferecingIdおよびReferencedIdは、次のいずれかのエンティティのIDを表します(参照/参照タイプに依存):
- 銀行(BankId tinyint 、名前 varchar(50))
- 国(CountryId tinyint 、名前 varchar(50))
- ラベル(LabelId tinyint 、名前 varchar(50))
- PaymentProviders (PaymentProviderId tinyint 、名前 varchar(50))
- PaymentOptions (PaymentOptionId tinyint 、名前 varchar(50))
将来、各エンティティにはいくつかの異なる列が追加される予定ですが、今のところこれは簡単にするためのスキーマです。
すべてのエンティティ(国を除く)と国の間には(1- )の接続があります。 ラベルには、(1-)のBanks、PaymentProviders、PaymentOptionsへの接続があります。 また、PaymentProvidersは(1- *)のPaymentProvidersへの接続を持っています
たとえば、BankId 201の銀行をCountryId 3003の国に接続する場合 BillingReferencesには、次のようなレコードがあります。 ReferencingType = 5 ReferencingId = 201 ReferencedType = 2 ReferencedId = 3003 IsActive = 1
拡張性を考慮して、接続の種類ごとに接続/参照テーブルを作成しませんでした-別のエンティティを追加する場合は、テーブルを追加し、BillingReferencesとBillingTypeにレコードを追加するだけです。
問題は、BillingReferencesと各エンティティの間に条件付き外部キーを構成できないことと、EntityFrameworkで構成/マッピングすることができないことです...
このタイプの実装を使用するチュートリアルまたは例を見つけることができませんでした。 接続ごとに参照テーブルを作成する必要がありますか、またはEntityFrameworkでこれを構成する方法はありますか?
助けてくれてありがとう:)
解決
わかりました、これを行う方法はありません。
もしあなたが本当にそうしない十分な理由がない限り、それぞれのタイプごとに別々のテーブルを作成します。あなたが言及する対価は良いものではありません、私見。
より多くのテーブルを保持することにより、キーに外部キー制約を設定でき、EFにうまく変換できます。また、パフォーマンスにも役立ちます:100万行の大きなass参照テーブルは、小さなテーブルよりもクエリに時間がかかります(常にすべての型の参照が必要な場合を除きます)。
他のヒント
Entity Frameworkでこれを行う方法がないだけでなく、SQLでもこれを行う方法がありません。 5つの異なるテーブルのいずれかを参照する外部キーは使用できません。
代わりに行うべきことは、親、抽象参照型を持ち、この親型の具象型サブタイプを作成することです。これで、1つのテーブルに対する外部キーは1つだけになりました。タイプごとのテーブルまたは階層マッピングごとのテーブルを選択できます。あなたが言及したタイプのいずれにも特別な列がまったくないことを考えると、階層マッピングごとのテーブルを選択することをお勧めします。
目的を達成できる唯一の方法は、サーバー側で処理を処理するトリガーを作成することです。そのようなFKを複数のテーブルにマッピングすることはできません。ただし、トリガーはそのロジックを処理できます。もちろん、それは完全にEFの外になります...
また、タイプごとに個別のテーブルを作成することをお勧めします。長い目で見れば保守が簡単だと思う。
まあ、私はユーザーInferisの提案をして、タイプごとに別々のテーブルを作成するつもりだと思います。
ご回答ありがとうございました-彼らはたくさんを助けてくれました:)
SQLでは、単一のテーブルに基づいて各タイプのビューを作成できます。 各ビューは結合を実行して、そのタイプのみに関連する情報を取得できます。 これにより、リンクをタイプを無視して全体として考えることもできます。