2012-06-02 18 views
6

यह अच्छी तरह से ज्ञात ईएफ उपयोगकर्ता के लिए एक साधारण सवाल होना चाहिए।कई रिश्तों के लिए कई मानचित्रण w/विदेशी कुंजी संदर्भ

मेरे पास निम्न स्कीमा (मेरे सिर में) है कि टेबल के बीच संबंधों को कैसे देखना चाहिए।

[FooBar]  [Foo]   [Bar] 

FooId PK,FK Id PK   Id PK 
BarId PK,FK BarId FK  Name 
IsRead  Name   Description 
       Description  

हालांकि, जब मैं करने की कोशिश का उपयोग कर एफई कोड-पहले यह संस्थाओं के रूप में मैं उन्हें व्याख्या की है के बीच संबंधों की व्याख्या करने में विफल रहता है स्कीमा उत्पन्न ([bar] मेज पर विदेशी कुंजी FooId कहते हैं) और विफल रहता है पूरी तरह से [FooBar] पुल तालिका बनाने के लिए।

यदि कोई मुझे ईएफ 4 कोड का उपयोग करके उपरोक्त स्कीमा को प्राप्त करने के तरीके पर मार्गदर्शन कर सकता है- पहले मैं इसकी सराहना करता हूं। समाधान में मेरे पीओसीओ मॉडल पर गुण शामिल हैं, धाराप्रवाह विन्यास या दोनों का एक संकर इससे कोई फर्क नहीं पड़ता - जब तक वांछित डेटाबेस स्कीमा बनाया जाता है।


POCO मॉडल:

public class Foo 
{ 
    public int Id { get; set; } 
    public string Text { get; set; } 
    public string Description { get; set; } 
    public int BarId { get; set; } 

    public Bar Bar { get; set; } /* bar entity */ 

    public virtual ICollection<Bar> BridgedBars { get; set; } 

    public Foo() 
    { 
     Bars = new List<Bar>(); 
    } 
} 

public class Bar 
{ 
    public int Id { get; set; } 
    public string Text { get; set; } 
    public string Description { get; set; } 

    public virtual ICollection<Foo> Foos { get; set; } 
    public virtual ICollection<Foo> BridgedFoos { get; set; } 

    public Bar() 
    { 
     Foos = new List<Foo>(); 
     BridgedFoos = new List<Foo>(); 
    } 
} 

public class FooBar 
{ 
    public int FooId { get; set; } 
    public int BarId { get; set; } 

    public virtual Foo Foo { get; set; } 
    public virtual Bar Bar { get; set; } 

    public bool IsRead { get; set; } 
} 
+0

आप के रूप में FooBar संबंध पर एक संपत्ति (IsRead) है जिसे आप संभवतः कोड से सेट करना चाहते हैं, दोनों Foo और Bar को उनके संबंधित संग्रह FooBars होने की आवश्यकता है। एक बार जब आप FooBar EF पर दोनों सिरों पर गुणों को मानचित्र बनाते हैं (यानी फू और बार में वर्चुअल संग्रह) संबंध को सही ढंग से बनाना चाहिए। प्रत्येक वर्ग को FooBar पर मैप करने के लिए HasMany()। के साथ आवश्यक()। –

उत्तर

8

आपका मॉडल वास्तव में एक विदेशी कुंजी FooIdBar जो संबंध Foo.BrideBars द्वारा परिभाषित के अंतर्गत आता है में पैदा करेगा। ईएफ में गुणों में से एक को इस नेविगेशन प्रॉपर्टी से संबंधित नहीं है क्योंकि दो उनमें से हैं और ईएफ विशिष्ट जोड़ी विशिष्ट रूप से निर्धारित नहीं कर सकता है। नतीजतन यह दूसरी छोर पर नेविगेशन संपत्ति के बिना Foo.BrideBars के लिए एक रिश्ता बनाता है। तो बोलने के लिए, एक अदृश्य Bar.Foo संपत्ति है जो विदेशी कुंजी का कारण बनती है।

डेटाबेस स्कीमा जिसे आप किसी मॉडल में मैप करना चाहते हैं, वास्तव में कई से अधिक रिश्ते का प्रतिनिधित्व नहीं करता है बल्कि इंटरमीडिएट "पुल" इकाई FooBar के साथ दो से एक से अधिक संबंधों का प्रतिनिधित्व करता है। सही संबंधों को परिभाषित करने के लिए आपको नेविगेशन गुणों में इस वर्ग का उपयोग करना होगा। यह इस तरह दिखेगा:

public class Foo 
{ 
    public int Id { get; set; } 
    public string Text { get; set; } 
    public string Description { get; set; } 

    public int BarId { get; set; } 
    public Bar Bar { get; set; } 

    public virtual ICollection<FooBar> FooBars { get; set; } 
} 

public class Bar 
{ 
    public int Id { get; set; } 
    public string Text { get; set; } 
    public string Description { get; set; } 

    public virtual ICollection<Foo> Foos { get; set; } 
    public virtual ICollection<FooBar> FooBars { get; set; } 

} 

public class FooBar 
{ 
    [Key, Column(Order = 0)] 
    public int FooId { get; set; } 
    [Key, Column(Order = 1)] 
    public int BarId { get; set; } 

    public virtual Foo Foo { get; set; } 
    public virtual Bar Bar { get; set; } 

    public bool IsRead { get; set; } 
} 

सही मॉडल इस मॉडल में सम्मेलनों का नामकरण करके पता लगाए जाएंगे। केवल FooBar इकाई के लिए एक कुंजी को स्पष्ट रूप से परिभाषित करना आवश्यक है क्योंकि संपत्ति के नाम सम्मेलनों को पूरा नहीं करते हैं (Id और FooBarId संपत्ति नहीं)। इस मॉडल में FooBar में एक समग्र कुंजी का उपयोग करना समझ में आता है।

मुझे लगता है कि, आपके वास्तविक वर्गों और गुणों का नाम Foo और Bar नहीं है। अपने असली नाम परंपराओं का पालन नहीं करते हैं तो आप संभवतः एनोटेशन के साथ संबंधों में बताने की - या Fluent एपीआई के साथ:

[FooBar]  [Foo]   [Bar] 

FooId PK,FK Id PK   Id PK 
BarId PK,FK BarId FK  Name 
IsRead   Name   Description 
       Description  
:

modelBuilder.Entity<Foo>() 
    .HasRequired(f => f.Bar) 
    .WithMany(b => b.Foos) 
    .HasForeignKey(f => f.BarId); 

modelBuilder.Entity<FooBar>() 
    .HasKey(fb => new { fb.FooId, fb.BarId }); // replaces the [Key] annotations 

modelBuilder.Entity<FooBar>() 
    .HasRequired(fb => fb.Foo) 
    .WithMany(f => f.FooBars) 
    .HasForeignKey(fb => fb.FooId); 

modelBuilder.Entity<FooBar>() 
    .HasRequired(fb => fb.Bar) 
    .WithMany(b => b.FooBars) 
    .HasForeignKey(fb => fb.BarId); 

अपने डेटाबेस स्कीमा में FooBar मेज एक समग्र प्राथमिक कुंजी होगा

लेकिन FooBar में पीके होने के लिए आवश्यक है क्योंकि ईएफ मॉडल में प्रत्येक इकाई के पास एक महत्वपूर्ण संपत्ति परिभाषित होनी चाहिए - या तो एकल या समग्र - जो डेटाबेस तालिका में प्राथमिक कुंजी के लिए मानचित्र करता है।

इस प्रश्न में - Create code first, many to many, with additional fields in association table - इस तरह के एक प्रकार के रिश्ते के साथ काम करने के तरीके के बारे में अधिक जानकारी है। (कभी कभी लोगों को भी यह कहते हैं "कई-से-अनेक पेलोड के साथ संबंध " (IsRead संपत्ति "पेलोड" अपने उदाहरण मॉडल में) है, लेकिन वास्तव में यह कई-से-अनेक नहीं है।)

+0

वही जो मैं खोज रहा था और हां 'फूबार' पर एक समग्र प्राथमिक कुंजी है मेरा इरादा था - बस इसका उल्लेख करना भूल गया! महान उत्तर और स्पष्टीकरण के लिए धन्यवाद! एक बार मेरी प्रोफ़ाइल * 15 अंक प्राप्त हो जाती है * मैं निश्चित रूप से वापस आऊंगा और ऊपर वोट दूंगा। – culturalanomoly

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