2017-09-12 23 views
5

में कई से कई लोगों ने ईएफ कोर 2.0, कोड फर्स्ट और फ्लुएंट एपीआई का उपयोग करते हुए कई से कई रिलेशनशिप उत्पन्न करने के उचित समाधान के लिए स्टैक ओवरफ्लो की खोज की है।फ्लुएंट एपीआई, एंटीटी फ्रेमवर्क कोर 2.0

एक साधारण परिदृश्य होगा:

public class Person 
{ 
    public Person() { 
     Clubs = new HashSet<Club>(); 
    } 
    public int PersonId { get; set; } 
    public virtual ICollection<Club> Clubs { get; set; } 
} 

public class Club 
{ 
    public Club() { 
     Persons = new HashSet<Person>(); 
    } 
    public int ClubId { get; set; } 
    public virtual ICollection<Person> Persons { get; set; } 
} 

कृपया मुझे ठीक कर लें im गलत है, लेकिन मैं ईमानदारी से नहीं एक सवाल है कि ऐसा करने के तरीके का वर्णन किया उपकरण का उपयोग कर पर एक विस्तृत विवरण शामिल मिल सकता है। क्या कोई यह समझा सकता है कि यह कैसे किया जाता है?

उत्तर

6

यह नहीं अभी तक में शामिल होने के लिए एक स्पष्ट वर्ग का उपयोग किए बिना एफई कोर में संभव है। इसे कैसे करें इसके उदाहरण के लिए here देखें।

गीथब पर एक खुला issue है जो स्पष्ट वर्ग की आवश्यकता के बिना ऐसा करने की क्षमता मांगता है, लेकिन यह अभी तक पूरा नहीं हुआ है।

अपने परिदृश्य का प्रयोग, उदाहरण मैं जुड़ा हुआ निम्नलिखित इकाई वर्गों की सिफारिश करेंगे:

public class Person 
{ 
    public int PersonId { get; set; } 
    public virtual ICollection<PersonClub> PersonClubs { get; set; } 
} 

public class Club 
{ 
    public int ClubId { get; set; } 
    public virtual ICollection<PersonClub> PersonClubs { get; set; } 
} 

public class PersonClub 
{ 
    public int PersonId { get; set; } 
    public Person Person { get; set; } 
    public int ClubId { get; set; } 
    public Club Club { get; set; } 
} 

निम्नलिखित OnModelCreating तो सेटअप के लिए इस्तेमाल किया जाएगा:

protected override void OnModelCreating(ModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<PersonClub>() 
     .HasKey(pc => new { pc.PersonId, pc.ClubId }); 

    modelBuilder.Entity<PersonClub>() 
     .HasOne(pc => pc.Person) 
     .WithMany(p => p.PersonClubs) 
     .HasForeignKey(pc => pc.PersonId); 

    modelBuilder.Entity<PersonClub>() 
     .HasOne(pc => pc.Club) 
     .WithMany(c => c.PersonClubs) 
     .HasForeignKey(pc => pc.ClubId); 
} 

खुला करने के लिए जाने के लिए सुनिश्चित करें यदि आप आवश्यकता महसूस करते हैं तो मैंने जो समस्या जुड़ी है और आपकी निराशा की आवाज उठाई है।

संपादित करें: खुले मुद्दा यह कुछ हद तक बोझिल पदानुक्रम के माध्यम से नेविगेट करने के लिए एक सरल Select का उपयोग कर पता चलता है। आदेश में एक PersonId से Club रों का संग्रह करने के लिए पाने के लिए, आप SelectMany उपयोग कर सकते हैं। उदा .:

var clubs = dbContext.People 
    .Where(p => p.PersonId == id) 
    .SelectMany(p => p.PersonClubs); 
    .Select(pc => pc.Club); 

मैं क्या यह वास्तव में एक "सबसे अच्छा अभ्यास" है पुष्टि नहीं कर सकते, लेकिन यह निश्चित चाल करना चाहिए और मैं इसे बहुत ज्यादा बदसूरत नहीं है कहने के लिए इसके उचित लगता है।

+0

तो यह 1-बहुत-कई -1 की तरह है? मुझे थोड़ा दुख है कि वे इस सुविधा का समर्थन नहीं करते हैं लेकिन उत्तर के लिए धन्यवाद। – Anonymous

+0

ऐसा लगता है कि आप अपनी उदासी से अकेले नहीं हैं। हालांकि ईएफ कोर टीम के लिए उचित रहें - उनके लिए बहुत कुछ है। –

+0

क्या आप मुझे कक्षा कक्षा के माध्यम से एक व्यक्ति आईडी के आधार पर क्लब पुनर्प्राप्त करने के लिए सबसे अच्छा अभ्यास LINQ समाधान दे सकते हैं? – Anonymous

1

इसलिए प्रत्येक Person में शून्य या अधिक Clubs और प्रत्येक Club शून्य या अधिक Persons है। जैसा कि आपने सही ढंग से कहा है, यह उचित से कई संबंध हैं।

आप शायद जानते हैं कि एक संबंधपरक डेटाबेस इस कई-से-अनेक संबंध लागू करने के लिए एक अतिरिक्त मेज की जरूरत है। इकाई ढांचे के बारे में अच्छी बात यह है कि यह इस रिश्ते को पहचानता है और आपके लिए यह अतिरिक्त टेबल बनाता है।

पहली नज़र में यह एक समस्या यह है कि इस अतिरिक्त तालिका अपने DbContext में एक dbSet नहीं है लगता है: "कैसे एक इस अतिरिक्त तालिका के साथ शामिल हो, तो मैं इसके लिए एक DbSet नहीं है प्रदर्शन करने के लिए?"।

सौभाग्य से, आप अपने प्रश्नों में इस अतिरिक्त तालिका उल्लेख करने के लिए जरूरत नहीं है।

यदि आपको "मुझे सब कुछ दें 'क्लब की तरह एक प्रश्न की आवश्यकता है ... प्रत्येक' व्यक्ति 'से ..." शामिल होने में मत सोचो। इसके बजाय ICollections का उपयोग करें!

सभी देश क्लब वे भाग लेने के साथ सभी "जॉन डो" व्यक्तियों प्राप्त करें:

var result = myDbContext.Persons 
    .Where(person => person.Name == "John Doe") 
    .Select(person => new 
    { 
     PersonId = person.Id, 
     PersonName = person.Name, 
     AttendedCountryClubs = person.Clubs 
      .Where(club => club.Type = ClubType.CountryClub), 
    }; 

इकाई की रूपरेखा है कि एक साथ शामिल होने के पहचान लेंगे अतिरिक्त कई-से-अनेक मेज की जरूरत है, और इस में शामिल होने के प्रदर्शन करेंगे, आप इस अतिरिक्त तालिका का उल्लेख किए बिना।

दौर दूसरा रास्ता: उनके "जॉन डो" व्यक्तियों के साथ पूरे देश क्लब प्राप्त करें:

var result = myDbContext.Clubs 
    .Where(club => club.Type = ClubType.CountryClub) 
    .Select(club => new 
    { 
     ClubId = club.Id, 
     ClubName = club.Name, 
     AnonymousMembers = club.Persons 
      .Where(person => person.Name == "John Doe"), 
    } 

मैं अनुभव किया है कि एक बार मैं जिसके परिणामस्वरूप संग्रह है कि मैं बजाय मिलती है मैं की चाहते में सोचने के लिए शुरू कर दिया इन संग्रहों को प्राप्त करने के लिए मुझे पता चला कि मैंने शायद ही कभी जुड़ने का उपयोग किया है। यह एक-से-कई संबंधों के साथ-साथ कई से अधिक संबंधों का मामला है। इकाई ढांचा आंतरिक रूप से उचित जुड़ने का उपयोग करेगा।

4

सही इस के लिए "सेटअप" है:

public class Person 
{ 
    public int PersonId { get; set; } 
    public virtual ICollection<PersonClub> PersonClubs { get; set; } 
} 

public class Club 
{ 
    public int ClubId { get; set; } 
    public virtual ICollection<PersonClub> PersonClubs { get; set; } 
} 

public class PersonClub 
{ 
    public int PersonId { get; set; } 
    public Person Person { get; set; } 
    public int ClubId { get; set; } 
    public Club Club { get; set; } 
} 
protected override void OnModelCreating(ModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<PersonClub>() 
     .HasKey(pc => new { pc.PersonId, pc.ClubId }); 
} 

तो, "गोंद-तालिका" विन्यस्त करने के लिए इस ब्लॉक आवश्यक नहीं @Kirk उदाहरण के रूप में है:

modelBuilder.Entity<PersonClub>() 
    .HasOne(pc => pc.Person) 
    .WithMany(p => p.PersonClubs) 
    .HasForeignKey(pc => pc.PersonId); 

modelBuilder.Entity<PersonClub>() 
    .HasOne(pc => pc.Club) 
    .WithMany(c => c.PersonClubs) 
    .HasForeignKey(pc => pc.ClubId); 
+0

यदि आप इसका उपयोग करते हैं [विदेशीकी] लिंक इकाई में विशेषता है जिसे आपको किसी भी कोड की आवश्यकता नहीं है। यहां तक ​​कि: दयनीय है कि यह पिछले संस्करण की तरह काम नहीं करता है। कोर के लिए देव के 4 वर्षों में वे पिछले संस्करण से मेल नहीं खा पाए हैं। –

संबंधित मुद्दे