Özelleştirilmiş bir birleştirme tablosu ile çoktan çoğa ilişki oluşturmak mümkün değildir. Çoktan çoğa ilişkide EF birleştirme tablosunu dahili ve gizli olarak yönetir. Modelinizde Entity sınıfı olmayan bir tablo. Ek özelliklere sahip böyle bir birleştirme tablosu ile çalışmak için aslında iki bire çok ilişki oluşturmanız gerekir. Şöyle görünebilir:
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; }
}
Şimdi LastName
= "Smith" ile üyelerin tüm yorumlarını bulmak istiyorsanız, örneğin şöyle bir sorgu yazabilirsiniz:
var commentsOfMembers = context.Members
.Where(m => m.LastName == "Smith")
.SelectMany(m => m.MemberComments.Select(mc => mc.Comment))
.ToList();
... ya da ...
var commentsOfMembers = context.MemberComments
.Where(mc => mc.Member.LastName == "Smith")
.Select(mc => mc.Comment)
.ToList();
Veya "Smith" adında üyelerin bir listesini oluşturmak için (birden fazla olduğunu varsayıyoruz) yorumlarıyla birlikte bir projeksiyon kullanabilirsiniz:
var membersWithComments = context.Members
.Where(m => m.LastName == "Smith")
.Select(m => new
{
Member = m,
Comments = m.MemberComments.Select(mc => mc.Comment)
})
.ToList();
MemberId
= 1 olan bir üyenin tüm yorumlarını bulmak istiyorsanız :
var commentsOfMember = context.MemberComments
.Where(mc => mc.MemberId == 1)
.Select(mc => mc.Comment)
.ToList();
Artık birleştirme tablonuzdaki özelliklere (çoktan çoğa ilişkide mümkün olmayacaktır) göre de filtreleyebilirsiniz, örneğin: 99'da özelliği olan üye 1'in tüm yorumlarına filtre uygulayın Something
:
var filteredCommentsOfMember = context.MemberComments
.Where(mc => mc.MemberId == 1 && mc.Something == 99)
.Select(mc => mc.Comment)
.ToList();
Tembel yükleme nedeniyle işler daha kolay olabilir. Yüklemeniz varsa, Member
açık bir sorgu olmadan yorumları alabilmeniz gerekir:
var commentsOfMember = member.MemberComments.Select(mc => mc.Comment);
Tembel yüklemenin yorumları otomatik olarak sahne arkasına getireceğini düşünüyorum.
Düzenle
Sadece eğlenmek için birkaç örnek daha varlıklar ve ilişkiler nasıl eklenir ve bu modelde nasıl silinir:
1) Bir üye ve bu üyenin iki yorumu oluşturun:
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) Üyenin üçüncü bir yorumunu ekleyin1:
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) Yeni üye oluşturun ve mevcut yorumla ilişkilendirin2:
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) Mevcut üye2 ve yorum3 arasında ilişki oluşturun:
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) Bu ilişkiyi tekrar silin:
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) Üye1'i ve yorumlarla olan tüm ilişkilerini silin:
var member1 = context.Members.Where(m => m.FirstName == "Pete")
.SingleOrDefault();
if (member1 != null)
{
context.Members.Remove(member1);
context.SaveChanges();
}
Bu ilişkileri siler MemberComments
arasındaki bire çok ilişkileri çok çünkü Member
ve MemberComments
arasında Comment
ve MemberComments
Kongre tarafından silme basamaklı ile yapılandırıldı. Ve durum budur MemberId
ve CommentId
in MemberComment
ve Member
ve Comment
navigasyon özellikleri için yabancı anahtar özellikleri olarak algılanır ve FK özellikleri null edilemeyen tipte int
olduğu için nihayetinde basamaklı-silme-kurulumuna neden olan ilişki gereklidir. Bence bu modelde mantıklı.