Không thể tạo mối quan hệ nhiều-nhiều với bảng tham gia tùy chỉnh. Trong mối quan hệ nhiều-nhiều, EF quản lý bảng tham gia nội bộ và ẩn. Đó là một bảng không có lớp Thực thể trong mô hình của bạn. Để làm việc với một bảng tham gia như vậy với các thuộc tính bổ sung, bạn sẽ phải tạo thực sự hai mối quan hệ một-nhiều. Nó có thể trông như thế này:
public class Member
{
public int MemberID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual ICollection<MemberComment> MemberComments { get; set; }
}
public class Comment
{
public int CommentID { get; set; }
public string Message { get; set; }
public virtual ICollection<MemberComment> MemberComments { get; set; }
}
public class MemberComment
{
[Key, Column(Order = 0)]
public int MemberID { get; set; }
[Key, Column(Order = 1)]
public int CommentID { get; set; }
public virtual Member Member { get; set; }
public virtual Comment Comment { get; set; }
public int Something { get; set; }
public string SomethingElse { get; set; }
}
Nếu bây giờ bạn muốn tìm tất cả các nhận xét của các thành viên với LastName
= "Smith", ví dụ bạn có thể viết một truy vấn như thế này:
var commentsOfMembers = context.Members
.Where(m => m.LastName == "Smith")
.SelectMany(m => m.MemberComments.Select(mc => mc.Comment))
.ToList();
... hoặc là ...
var commentsOfMembers = context.MemberComments
.Where(mc => mc.Member.LastName == "Smith")
.Select(mc => mc.Comment)
.ToList();
Hoặc để tạo danh sách các thành viên có tên "Smith" (chúng tôi giả sử có nhiều hơn một) cùng với nhận xét của họ, bạn có thể sử dụng phép chiếu:
var membersWithComments = context.Members
.Where(m => m.LastName == "Smith")
.Select(m => new
{
Member = m,
Comments = m.MemberComments.Select(mc => mc.Comment)
})
.ToList();
Nếu bạn muốn tìm tất cả ý kiến của một thành viên với MemberId
= 1:
var commentsOfMember = context.MemberComments
.Where(mc => mc.MemberId == 1)
.Select(mc => mc.Comment)
.ToList();
Giờ đây, bạn cũng có thể lọc theo các thuộc tính trong bảng tham gia của mình (điều này không thể thực hiện được trong mối quan hệ nhiều-nhiều), ví dụ: Lọc tất cả các nhận xét của thành viên 1 có thuộc tính 99 Something
:
var filteredCommentsOfMember = context.MemberComments
.Where(mc => mc.MemberId == 1 && mc.Something == 99)
.Select(mc => mc.Comment)
.ToList();
Bởi vì lười tải mọi thứ có thể trở nên dễ dàng hơn. Nếu bạn đã tải, Member
bạn sẽ có thể nhận được các bình luận mà không cần truy vấn rõ ràng:
var commentsOfMember = member.MemberComments.Select(mc => mc.Comment);
Tôi đoán rằng tải lười biếng sẽ lấy các bình luận tự động đằng sau hậu trường.
Biên tập
Chỉ để cho vui một vài ví dụ nữa về cách thêm các thực thể và mối quan hệ và cách xóa chúng trong mô hình này:
1) Tạo một thành viên và hai bình luận của thành viên này:
var member1 = new Member { FirstName = "Pete" };
var comment1 = new Comment { Message = "Good morning!" };
var comment2 = new Comment { Message = "Good evening!" };
var memberComment1 = new MemberComment { Member = member1, Comment = comment1,
Something = 101 };
var memberComment2 = new MemberComment { Member = member1, Comment = comment2,
Something = 102 };
context.MemberComments.Add(memberComment1); // will also add member1 and comment1
context.MemberComments.Add(memberComment2); // will also add comment2
context.SaveChanges();
2) Thêm nhận xét thứ ba của thành viên1:
var member1 = context.Members.Where(m => m.FirstName == "Pete")
.SingleOrDefault();
if (member1 != null)
{
var comment3 = new Comment { Message = "Good night!" };
var memberComment3 = new MemberComment { Member = member1,
Comment = comment3,
Something = 103 };
context.MemberComments.Add(memberComment3); // will also add comment3
context.SaveChanges();
}
3) Tạo thành viên mới và liên kết nó với nhận xét hiện có2:
var comment2 = context.Comments.Where(c => c.Message == "Good evening!")
.SingleOrDefault();
if (comment2 != null)
{
var member2 = new Member { FirstName = "Paul" };
var memberComment4 = new MemberComment { Member = member2,
Comment = comment2,
Something = 201 };
context.MemberComments.Add(memberComment4);
context.SaveChanges();
}
4) Tạo mối quan hệ giữa thành viên hiện tại2 và bình luận3:
var member2 = context.Members.Where(m => m.FirstName == "Paul")
.SingleOrDefault();
var comment3 = context.Comments.Where(c => c.Message == "Good night!")
.SingleOrDefault();
if (member2 != null && comment3 != null)
{
var memberComment5 = new MemberComment { Member = member2,
Comment = comment3,
Something = 202 };
context.MemberComments.Add(memberComment5);
context.SaveChanges();
}
5) Xóa mối quan hệ này một lần nữa:
var memberComment5 = context.MemberComments
.Where(mc => mc.Member.FirstName == "Paul"
&& mc.Comment.Message == "Good night!")
.SingleOrDefault();
if (memberComment5 != null)
{
context.MemberComments.Remove(memberComment5);
context.SaveChanges();
}
6) Xóa thành viên1 và tất cả các mối quan hệ của nó với các bình luận:
var member1 = context.Members.Where(m => m.FirstName == "Pete")
.SingleOrDefault();
if (member1 != null)
{
context.Members.Remove(member1);
context.SaveChanges();
}
Này sẽ xoá các mối quan hệ trong MemberComments
quá vì các mối quan hệ một-nhiều giữa Member
và MemberComments
và giữa Comment
và MemberComments
được thiết lập với tầng xóa theo quy ước. Và đây là trường hợp vì MemberId
và CommentId
trong MemberComment
được phát hiện như là thuộc tính khóa ngoại cho Member
và Comment
chuyển hướng tài sản và kể từ khi các thuộc tính FK là loại không nullable int
mối quan hệ là yêu cầu mà cuối cùng làm cho tầng-delete-setup. Làm cho ý nghĩa trong mô hình này, tôi nghĩ.