0

2つのエンティティオブジェクトがあります。

   public class Contact
    {
        public int ContactID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }

        public ICollection<Friend> Friends { get; set; }

    }

と友達:

public class Friend
{
    [Key, Column(Order = 1)]
    public int ContactId1 { get; set; }
    [Key, Column(Order = 1)]
    public int ContactId2 { get; set; }
    public DateTime DateCreated { get; set; }
}

ここで、ContactId1はContactIDにマップされ、ContactId2は別のContactIdにマップされます。

が適切な関係で生成されていることを確認するにはどうすればよいですか?

4

2 に答える 2

2

Friendクラスを拡張する必要があります。

public class Friend
{
    [Key, Column(Order = 0), ForeignKey("Contact1")]
    public int ContactId1 { get; set; }
    public Contact Contact1 { get; set; }

    [Key, Column(Order = 1), ForeignKey("Contact2")]
    public int ContactId2 { get; set; }
    public Contact Contact2 { get; set; }

    public DateTime DateCreated { get; set; }
}

Friendsのコレクションに属性を追加しますContact

[InverseProperty("Contact1")]
public ICollection<Friend> Friends { get; set; }

(注釈の代わりに Fluent API を使用することもできます。)

その結果、2 つの 1 対多の関係になります (このモデルを多対多としてマップすることはできません)。1 つ目は と の間Contact.FriendsFriend.Contact1、2 つ目はFriend.Contact21 つのエンドポイントです。のエンドポイントFriendはモデルで公開されていません。

たとえば、今日より前に作成された特定の連絡先のすべての友人の連絡先を照会できます。

DateTime today = DateTime.Now.Date;
IEnumerable<Contact> friendContacts = context.Contacts
    .Where(c => c.ContactId == givenId)
    .Select(c => c.Friends
        .Where(f => f.DateCreated < today)
        .Select(f => f.Contact2))
    .SingleOrDefault();

エイト

Friendに 2 つの必要な関係があるため、上記のマッピングは機能しませんContact。必要な 1 対多のリレーションシップの既定では、EF はカスケード削除を有効にしますが、これは同時に 2 つのリレーションシップに対して許可されていません。カスケード削除を無効にするには、Fluent API でマッピングを書き直す必要があります。これは、データ注釈では不可能なためです。

public class Contact
{
    public int ContactID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }

    public ICollection<Friend> Friends { get; set; }
}

public class Friend
{
    public int ContactID1 { get; set; }
    public Contact Contact1 { get; set; }

    public int ContactID2 { get; set; }
    public Contact Contact2 { get; set; }

    public DateTime DateCreated { get; set; }
}

次に、派生コンテキストでオーバーライドOnModelCreatingします。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Friend>()
        .HasKey(f => new { f.ContactID1, f.ContactID2 });

    modelBuilder.Entity<Friend>()
        .HasRequired(f => f.Contact1)
        .WithMany(c => c.Friends)
        .HasForeignKey(f => f.ContactID1);

    modelBuilder.Entity<Friend>()
        .HasRequired(f => f.Contact2)
        .WithMany()
        .HasForeignKey(f => f.ContactID2)
        .WillCascadeOnDelete(false);  // <- Important
}
于 2012-04-27T20:12:10.383 に答える
0

連絡先で2人を紹介する2行の友人が必要だと思いますよね?はいの場合、友人のインスタンスに 2 つの作成が必要です。Entity Framework Code First は、既定では、キーの関係をプロパティの名前で認識します。したがって、Friend クラスでは、エンティティの名前が Contact であるため、プロパティの名前は ContactId にする必要があります。

public class Contact
{
    public int ContactID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }

    public ICollection<Friend> Friends { get; set; }

}

public class Friend
{
    public int ContactId { get; set; }
    public DateTime DateCreated { get; set; }
}

編集

友達に多くの連絡先を持たせたい場合は、関係テーブルが必要です。

public class Contact
{
    public int ContactID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }

    public ICollection<Friend> Friends { get; set; }

}

public class Friend
{
    public int FriendId { get; set; }
    public DateTime DateCreated { get; set; }
}

public class FriendContactRel 
{
    [Key, Column(Order = 0)]
    public int ContactID { get; set; }
    [Key, Column(Order = 1)]
    public int FriendId { get; set; }
}
于 2012-04-27T19:26:46.880 に答える