0

データ構造

これは比較的単純なデータ構造ですが、これをモデル化するための最適な EF 戦略を見つけるのに苦労しています。それは明らかにTable Per Hierarchyではありません。そこで、Table Per Type を試してみましたが、Client と Person、または Customer と Person の関係が気に入りませんでした。Table Per Concrete Type について読んだ後、そのモデルにも従いません。この ERD をどのようにモデル化しますか?

#

アップデート

#

その背後にあるビジネス ユース ケースは、複数の企業と取引することです。これらの企業の中には、他の企業を買収したものもあります。親会社 (Acme) は長年の顧客です。子会社 (Zeta) は長年のクライアントです。Acme が Zeta を買収したとき、会社間の関係を処理する担当者を 1 人配置しました (Adam)。Adam は、イベントを通知する必要がある 2 つの異なる電子メール アドレスを持っています。adam@acme.com は顧客通知を受け取ります。adam@zeta.com はクライアント通知を受け取ります。それが私がそれをそのようにモデル化した理由です。Adam はちょっと強迫観念的で、通知を個別のメールボックスに分けておくのが好きです。プログラマーとして、私は Adam が好きではありません。:D

システムには、クライアントと顧客以外にもいくつかの分類があります。また、ベンダー、技術者、ディストリビューターもいます。以下の提案と非常によく似たモデリングを行いましたが、Email テーブルをタイプ固有のテーブル (CustomerEmail と ClientEmail) に分割しました。完璧ではありませんが、「やり遂げる」ためには機能します。

4

1 に答える 1

3

人はクライアントと顧客の両方になることができます。

その後ClientCustomerから継承することはできませんPerson。これを構成でモデル化する必要があります。Not : APerson ClientまたはCustomerです。代わりに: APerson にはClient、および/またはの属性がありますCustomer

EF では、これは 2 つの 1 対 1 の関係になります。

public class Person
{
    public int PersonId { get; set; }
    public Client Client { get; set; }
    public Customer Customer { get; set; }
}

Clientを参照する参照Customerを持つことができます。(この参照を持つ必要はありませんが、このナビゲーション プロパティを介して FirstName と LastName へのアクセスを有効にすることは理にかなっています。)PersonPerson

public class Client / Customer
{
    public int PersonId { get; set; }
    public Person Person { get; set; }
}

Person は常にaと属性の両方を持つ必要はないと思いますが、場合によっては 1 つだけ (または 0 でさえありますか?) 必要があります。この場合、両方のリレーションシップのプリンシパルであり、/は依存関係です。Fluent API を使用すると、次のようにモデル化されます。ClientCustomerPersonClientCustomerPersonPersonClientCustomer

modelBuilder.Entity<Person>()
    .HasOptional(p => p.Client)
    .WithRequired(c => c.Person);

modelBuilder.Entity<Person>()
    .HasOptional(p => p.Customer)
    .WithRequired(c => c.Person);

と の関係はPersonNote2 つの通常の 1 対多の関係です。Person2 つのナビゲーション コレクションを持つことができます...

public ICollection<Note> NotesAsNotator { get; set; }
public ICollection<Note> NotesAsNotatee { get; set; }

...そして、2 つの外部キー プロパティと共にNote2 つの参照を持つことができます (これらはモデルで公開する必要はありませんが、しばしば役立ちます)。Person

public int NotatorIDFK { get; set; }
public Person Notator { get; set; }

public int NotateeIDFK { get; set; }
public Person Notatee { get; set; }

そして、関係は次のように Fluent API で定義されます。

modelBuilder.Entity<Person>()
    .HasMany(p => p.NotesAsNotator)
    .WithRequired(n => n.Notator)
    .HasForeignKey(n => n.NotatorIDFK)
    .WillCascadeOnDelete(false);

modelBuilder.Entity<Person>()
    .HasMany(p => p.NotesAsNotatee)
    .WithRequired(n => n.Notatee)
    .HasForeignKey(n => n.NotateeIDFK)
    .WillCascadeOnDelete(false);

カスケード削除はここで (少なくとも 2 つのリレーションシップの 1 つに対して) 無効にする必要があります。そうしないと、少なくとも SQL Server では禁止されている 2 つのリレーションシップのために、複数のカスケード削除パスを介してPerson削除できます。Notes

Locationと とClientと の間の関係もLocationCustomerそれぞれ 2 つの 1 対多の関係 (合計 4 つ) であり、 に 4 つのコレクションがLocationあり、 と に 2 つの参照LocationClientありCustomerます。これらは、上記の関係と同様にモデル化されています。

ClientEmailとの関係は 1 対 1 ですが、明らかにEF でサポートされていない外部キー (一意のキー制約付き?) を使用しCustomerているため、問題です。コメントで Gert Arnold が既に質問したように: なぜとの関係がないのですか? この 2 つの関係は、ある人が顧客としてではなく顧客として別の電子メール アドレスを持つことができることを表しているのでしょうか? モデルのこの部分がわかりません。EmailPersonIDFKPersonEmail

于 2013-02-07T21:14:23.763 に答える