2016-03-22 13 views
2

EF 6.0でコードファーストとデータ注釈を使用しようとしていますが、 2つのクラスのモデル:イベントの主催者と参加者することができ、基本的には従業員:2つのクラス間で複数の異なる(1対多、多対多)関係があるときにモデルクラスに注釈を付ける方法

public class Employee 
{ 
    [Key] 
    public Guid Id { get; set; } 
    public string name { get; set; } 

    public virtual ICollection<Event> event { get; set; } 
} 

public class Event 
{ 
    [Key] 
    public Guid Id { get; set; } 
    public string name { get; set; } 

    [ForeignKey("organizer")] 
    public Guid organizerId { get; set; } 
    public virtual Employee organizer { get; set; } 

    public virtual ICollection<Employee> atendees { get; set; } 
} 

私はEFが、それは驚くほどの従業員間の多対多の関係を生成しません。これらのクラスからデータベースを生成してみましょう(従業員イベントの多対多テーブルはありません)、従業員にはイベントIDの外部キーが生成されます。 (私は理由がありません。)

もちろん、Fluent-APIを使用して適切なdbマッピングを直接作成できますが、これをデータアノテーションで実現する方法があるかどうかは疑問でした。

+2

'event'は予約済みのキーワードです。それはおそらく問題ではありませんが、そのプロパティを呼び出すことはできません。しかし、このコレクションは、従業員が主催者であるか、出席者であるすべてのイベントに適用されますか?おそらく、あなたは[InverseProperty](http://www.entityframeworktutorial.net/code-first/inverseproperty-dataannotations-attribute-in-code-first.aspx)属性で少しでも遊ぶ必要があります。 – Corak

+0

多分 'Event.organizer'を' Employee.event'にmany-to-oneとしてマッピングします。 –

+0

タイトルが実際にあなたの質問をカバーするようにあなたの質問を編集してください。 – CodeCaster

答えて

2

私はEfのあなたを考えている理由です、Employee organizerはEFにを混乱だと思います1対多の関係を持つ。その場合は@CorakはInversePropertyの詳細については、また流暢APIなし

を問題を解決するために十分であるべき

public class Employee 
{ 
    [Key] 
    public Guid Id { get; set; } 
    public string name { get; set; } 

    [InverseProperty("atendees")] 
    public virtual ICollection<Event> event { get; set; } 
} 

public class Event 
{ 
    [Key] 
    public Guid Id { get; set; } 
    public string name { get; set; } 

    [ForeignKey("organizer")] 
    public Guid organizerId { get; set; } 
    public virtual Employee organizer { get; set; } 

    [InverseProperty("event")] 
    public virtual ICollection<Employee> atendees { get; set; } 
} 

を言ったように、あなたはInversePropertyを使用することによってそれを解決することができますあなたは一見を見ることができますthis answer

+0

ありがとう、エンリケ - これは私が探していたものです。魅力のように動作します。もちろん、私はまだIvanが述べたように循環カスケード削除の問題がありますが、それは別の問題です。 – Laszlo

1

あなたの説明しているモデルは、あなたにとってはシンプルだと思うかもしれませんが、データベースデザインの観点からはそれほど些細なものではないので、EFは「明白な」構成を正しく導出できません。

まず、あなたが持っている実際にEmployeeEvent間の2つの関係:

(1)1対多の従業員 - >従業員が
(2)多対多の従業員を組織しているイベントを記述するイベント - >従業員が

に出席されたイベントを記述したイベントは、だから、モデルは次のようにする必要があります:

public class Employee 
{ 
    [Key] 
    public Guid Id { get; set; } 
    public string name { get; set; } 

    public virtual ICollection<Event> organizingEvents { get; set; } 
    public virtual ICollection<Event> attendingEvents { get; set; } 
} 

public class Event 
{ 
    [Key] 
    public Guid Id { get; set; } 
    public string name { get; set; } 

    [ForeignKey("organizer")] 
    public Guid organizerId { get; set; } 
    public virtual Employee organizer { get; set; } 

    public virtual ICollection<Employee> attendees { get; set; } 
} 

追加の問題は、このようなモデルレコード生成ということです循環カスケード削除問題の可能性があります。制限について言えば、データアノテーションでカスケードオプションを指定することはできないため、実際には流暢な設定が必要です。それはとにかくそれを必要と一度、なぜ流暢APIに完全に関係を設定でき、データの注釈を気:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<Employee>() 
     .HasMany(e => e.organizingEvents) 
     .WithRequired(e => e.organizer) 
     .HasForeignKey(e => e.organizerId) 
     .WillCascadeOnDelete(false); 

    modelBuilder.Entity<Employee>() 
     .HasMany(e => e.attendingEvents) 
     .WithMany(e => e.attendees); 
} 
+0

ありがとう、イワン、はい、あなたは正しいです、循環カスケードの問題はとにかくそこにあります。したがって、流動的な使用は長期(およびスケーラブル)なルートです。 – Laszlo

0

@Ivan Stoevの答えとして、あなたは、あなたが本当にすることでこれを実現したいwell.Ifと流暢なAPIを使用することができますデータ注釈、あなたは中央のテーブルに対して1つのクラスを持つことができますし、多くのrelationships.Tryに1で、次をマッピングすることができます

public class Employee 
    { 
     [Key] 
     public Guid Id { get; set; } 
     public string name { get; set; } 
     public virtual ICollection<middle_table> Middle_table{ get; set; } 
     public virtual ICollection<Event> event { get; set; } 
    } 

    public class Event 
    { 
     [Key] 
     public Guid Id { get; set; } 
     public string name { get; set; } 
     [ForeignKey("organizer")] 
     public Guid organizerId { get; set; } 
     public virtual Employee organizer { get; set; } 
     public virtual ICollection<middle_table> Middle_table{ get; set; } 
    } 
    public class your_middle_class 
    { 
    public Guid Id { get; set; } 
    public virtual Employee organizer { get; set; } 
    public virtual Event Event{ get; set; } 
    } 
関連する問題