您需要扩展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; }
}
和属性在Contact
添加到Friends
集合:
[InverseProperty("Contact1")]
public ICollection<Friend> Friends { get; set; }
(你也可以用流利的API,而不是注解)
结果是两个一对多关系(您不能将此模型映射为多对多)。第一个是Contact.Friends
和Friend.Contact1
,第二个是Friend.Contact2
作为一个端点。模型中未显示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();
EIT
上述映射不起作用,因为Friend
有两个必需的关系Contact
。默认情况下,对于所需的一对多关系,EF将启用级联删除,但不允许两个关系同时使用。我们需要重写用流利的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
}
[多对一的可能重复许多关系在代码优先EF4](http://stackoverflow.com/questions/3148844/many-to-many-relationship-in-code-first-ef4) – StriplingWarrior 2012-04-27 19:24:23