web-dev-qa-db-ja.com

外部キーを宣言しないナビゲーションプロパティ

私のすべてのモデルには、少なくとも2つの関連付けが含まれています。これをef4でモデリングするとき、流暢なインターフェイスを使用して2番目の外部キープロパティなしでこれを行うことができました。 ForeignKeyは、文字列パラメーターを必要とするという事実を除いて、使用する適切な属性のようです。

だから私の質問は、ナビゲーションプロパティを持ち、属性を使用してそのように宣言できるかどうかです。

public class User : IAuditable
{
    // other code

    public virtual User Creator { get; set; }

    public virtual User Modifier { get; set; }
}
31
Daniel Little

データ属性だけで関係を定義することはできないと思います。問題は、EFのマッピング規則がCreatorModifierが1つの同じ関係の両端であると想定しているが、この関連付けのプリンシパルと依存関係が何であるかを判断できないことです。サポートされている属性のリストで確認できる限り、プリンシパルと依存エンドをデータアノテーションで定義するオプションはありません。

それとは別に、実際に必要なのは2つの関係であり、どちらもモデルで公開されていない終了を伴います。これは、モデルがマッピング規則に関して「型破り」であることを意味します。 (CreatorModifierの関係は実際にはナンセンスです-セマンティックの観点から)

したがって、Fluent APIでは、次のようにします。

modelBuilder.Entity<User>()
            .HasRequired(u => u.Creator)
            .WithMany();

modelBuilder.Entity<User>()
            .HasRequired(u => u.Modifier)
            .WithMany();

Userは、他の多くのユーザーレコードの作成者または変更者になることができるためです。正しい?

Fluent APIを使用せず、DataAnnotationsのみを使用してこれら2つの関係を作成する場合は、次のように、関連の多端をモデルに導入する必要があると思います。

public class User
{
    public int UserId { get; set; }

    [InverseProperty("Creator")]
    public virtual ICollection<User> CreatedUsers { get; set; }
    [InverseProperty("Modifier")]
    public virtual ICollection<User> ModifiedUsers { get; set; }

    [Required]
    public virtual User Creator { get; set; }
    [Required]
    public virtual User Modifier { get; set; }
}

ここでは、CreatorおよびModifierが必要であると想定しています。それ以外の場合は、[Required]属性を省略できます。

Fluent APIを使用することが理にかなっており、Fluent構成を回避するためだけにモデルを変更するよりも良いケースは明らかだと思います。

35
Slauma