2009-06-03 6 views
11

तो एक सामान्य मॉडल में जहां आपके माता-पिता हैं, जिनमें कई बच्चे और बच्चे हो सकते हैं, जिनमें केवल एक माता-पिता हो, आप बच्चों को जोड़ने का प्रबंधन कैसे करते हैं। मैं इस दृष्टिकोण का उपयोग कर रहा हूं;NHibernate माता-पिता-बाल संग्रह को संभालने के लिए सर्वोत्तम अभ्यास

public class Parent 
{ 
    public Parent() 
    { 
     Children = new List<Child>(); 
    } 

    public IList<Child> Children 
    { 
     get; 
     private set; 
    } 
} 

public class Child 
{ 
    public Parent Parent 
    { 
     get; 
     set; 
    } 
} 

var child = new Child(); 
var parent = new Parent(); 
parent.Children.Add(child); 
child.Parent = parent; 

समस्या है कि हर जगह मैं एक नए बच्चे मैं दोनों बच्चे और माता पिता और एक दर्द की अपनी एक सा के लिए एक संदर्भ जोड़ने के लिए याद करने के लिए मिल गया है जोड़ना चाहते है। मैं सिर्फ अभिभावक वर्ग में एक एडचल्ड विधि जोड़ सकता हूं और बच्चों को जोड़ने के लिए जिम्मेदार बना सकता हूं - समस्या यह है कि बच्चों की संपत्ति और विधि के माध्यम से बच्चे को जोड़ने के 2 तरीके हैं। तो क्या यह एक बेहतर समाधान है?

public class Parent 
{ 
    public Parent() 
    { 
     children = new List<Child>(); 
    } 

    private IList<Child> children 
    { 
     get; 
     private set; 
    } 

    public IEnumerable<Child> Children 
    { 
     get 
     { 
      return children; 
     } 
    } 

    public void AddChild(Child child) 
    { 
     children.Add(child); 
     child.Parent = this; 
    } 
} 

इस पर सर्वोत्तम प्रथाओं के लिए किसी भी guidences हैं, और आप क्या करते हैं?

उत्तर

2

मुझे लगता है कि जैसे यह करने के सिवाय इसके कि मैं निजी सूची के लिए संपत्ति का उपयोग नहीं करते

private IList<Child> _children 
public IEnumerable<Child> Children 
{ 
    get 
    { 
     return children; 
    } 
} 
+2

यह एक अच्छा समाधान है लेकिन इस बात की कमी के साथ कि उपभोक्ता ने बच्चों को पर इस्लाम करने का मौका दिया, तो वह सूची तक पहुंच जाएगा और इसे संशोधित कर सकता है .. अन्य तरीका ReadOnlyCollection <> का उपयोग कर सकता है। –

10

यह एनएचबीर्नेट समस्या नहीं है।

आपको AddChild विधि को लागू करना चाहिए। कक्षाएं उनकी स्थिरता के लिए ज़िम्मेदार हैं, इसलिए उन्हें उपलब्ध कुछ भी नहीं दिखाना चाहिए जो उपलब्ध नहीं होना चाहिए। उदाहरण के लिए, (परिवर्तनीय) बच्चों की सूची छिपी जानी चाहिए। एक आईनेमरेबल का खुलासा करना एक अच्छा विचार है।

आपका दूसरा कोड एक अच्छा प्रारंभिक बिंदु है। आपको शायद कुछ और तरीकों की आवश्यकता है, जैसे RemoveChild या CoundChildren।

+0

दूसरे उदाहरण की बात करते हुए मेरी एकमात्र चिंता यह है कि यह लिंक से NHibernate के साथ कैसे काम कर सकता है। चूंकि वास्तविक मैप की गई संपत्ति अब निजी है, मुझे लगता है कि यह दृश्यमान नहीं होगा। कोई विचार? – Gareth

+0

आप अपने मैपिंग में निर्दिष्ट कर सकते हैं कि मूल्य निर्धारित करते समय NHibernte को संपत्ति के बजाय फ़ील्ड का उपयोग करना चाहिए। (उदाहरण के लिए एक्सेस विशेषता पर एक नज़र डालें)। –

+0

हां, जो मैं प्राप्त कर रहा था वह यह था कि जब लिंक से एनएचबर्ननेट समाप्त हो जाता है तो यदि आप निजी हैं और सार्वजनिक पहुंच केवल मूल संग्रह का संदर्भ देता है तो आप इसका उपयोग कैसे कर सकते हैं। उदाहरण के लिए। session.Linq () .Where (x => x.Children.Name.Equals ("Jonnie")) – Gareth

5

मैं इस तरह यह कार्य करें:

public class Parent 
{ 
    private ISet<Child> _children = new HashedSet<Child>(); 

    public ReadOnlyCollection<Child> Children 
    { 
     get{ return new List(_children).AsReadOnly(); } 
    } 

    public void AddChild(Child c) 
    { 
     if(c != null && !_children.Contains (d)) 
     { 
      c.Parent = this; 
      _children.Add (c); 
     } 
    } 
} 

तो, वास्तव में, कि एक सा क्या स्टीफन रूप में अच्छी तरह कहते है। मैं सिर्फ बच्चों की सूची की एक पाठ-प्रतिलिपि का पर्दाफाश करता हूं, ताकि आप माता-पिता के बच्चों पर आसानी से पुन: प्रयास कर सकें और माता-पिता के बच्चों की संख्या प्राप्त कर सकें। माता-पिता को बच्चों को जोड़ना और निकालना, AddChild & RemoveChild सदस्य विधियों का उपयोग करके किया जाना है।

+1

एक सेट डुप्लिकेट नहीं जोड़ देगा इसलिए यह जांचने की कोई आवश्यकता नहीं है कि बच्चा पहले से मौजूद है या नहीं। –

-1

मुझे सभी अतिरिक्त AddXXX() और RemoveXXX() मेरी इकाई इंटरफेस को छेड़छाड़ करने की विधि पसंद नहीं है। इसके बजाए, मेरे पास एक कस्टम सूची है जो घटनाओं को बढ़ाती है जब Add() और Remove() विधियों को बुलाया जाता है।

जोड़ने तो ईवेंट हैंडलर्स में क्या होता है:

public class Course() 
{ 
    public Course() 
    { 
    this.Topics = new EntityList<Topic>(); 
    this.Topics.AddItem += new AddItemEventHandler<Topic>(Topic_AddItem); 
    this.Topics.RemoveItem += new RemoveItemEventHandler<Topic>(Topic_RemoveItem); 
    } 

    public EntityList<Topic> Topics { get; private set; } 

    private void Topic_AddItem(Topic item, object args) 
    { 
    // Replace with your linking code: 
    EntityLinker.Link(this).With(item, args); 
    } 

    private void Topic_RemoveItem(Topic item, object args) 
    { 
    // Replace with your unlinking code: 
    EntityLinker.Unlink(this).From(item, args); 
    } 
} 
+4

मुझे यह दृष्टिकोण पसंद नहीं है। :) दृश्यों के पीछे बहुत 'जादू' चल रहा है। मुझे याद है कि अयेंडे ने एक बार इस दृष्टिकोण का भी उपयोग किया था (एनएचबर्ननेट जेनेरिक में यदि मुझे गलत नहीं है), लेकिन अब मैं उसे इस दृष्टिकोण का उपयोग करके नहीं देखता हूं। मुझे लगता है कि 'लिंक' तर्क बहुत छिपा हुआ है। इसके आगे, मैं इंटरफ़ेस की अव्यवस्था के रूप में अपनी संस्थाओं में Addxxxx विधियों को जोड़ने को नहीं देखता। इसके अलावा, मुझे यह बेहतर लगता है क्योंकि यह अधिक स्पष्ट है। –

+0

यह मेरे लिए बहुत पठनीय नहीं दिखता है। – UpTheCreek

1

मैं के साथ सार्वजनिक IEnumerable उपयोग कर रहा हूँ जोड़ें | विधियों के दृष्टिकोण निकालें।

हालांकि मुझे यह बहुत पसंद नहीं है, क्योंकि यह सहज नहीं है, और वर्ग परिभाषा को विनियमित करता है।

मुझे आश्चर्य है कि लोग कस्टमकॉलेक्शन का उपयोग क्यों नहीं करते हैं, जहां वे ओवरराइड जोड़ें, निकालें, फ़ंक्शन बदलें ?? (जैसे यह एमएस कोड में हर जगह किया जाता है) ????

0

मैं इस प्रश्न के स्वीकृत समाधान का समर्थन करता हूं, हालांकि प्रस्तुत किए गए समाधान को पूरा नहीं किया गया है, क्योंकि निजी क्षेत्रों का उपयोग करने के लिए मैपर्स में कुछ अतिरिक्त कॉन्फ़िगरेशन की आवश्यकता होती है।

public partial class Test 
{ 
    private readonly IList<Child> children = new List<Child>(); 
    public virtual IEnumerable<Child> Children 
    { 
     get 
     { 
      return children; 
     } 
    } 
} 

ध्यान दें कि सार्वजनिक रूप से उजागर संग्रह NHibernate इसका इस्तेमाल करने के लिए आभासी होना चाहिए: अन्य लोगों के लाभ के लिए, निम्नलिखित पूर्ण समाधान है।मैं इसे एक पठनीय क्षेत्र बनाना भी पसंद करता हूं जिसे क्लास बनाया जाता है ताकि यह सुनिश्चित किया जा सके कि यह सभी परिदृश्यों में मौजूद है। यहाँ जुड़े नक्शाकार है:

public class TestMap : ClassMap<Test> 
{ 
    ... 
    HasMany(s => s.Children).Access.CamelCaseField(); 
} 

पहुँच संपत्ति NHibernate बताता है कि जब मॉडल में मान मैप निजी क्षेत्र का उपयोग करें। एक्सेस नाम पर अन्य विकल्प भी हैं जो विभिन्न नामकरण कॉन्फ़िगरेशन का उपयोग करने की अनुमति देते हैं।

0

आप अपने DB में एक विदेशी कुंजी है, और आप पहचान (SQL सर्वर) का उपयोग कर रहे अपनी प्राथमिक कुंजी उत्पन्न करने के लिए हैं, तो आप नीड माता-पिता के लिए बच्चे से backlink जा रहे हैं। अन्यथा, सम्मिलन बच्चे पर शिकायत करेगा क्योंकि निषेध को माता-पिता आईडी के लिए कुछ और आगे करने की आवश्यकता है, लेकिन यह अभी तक नहीं किया है।

बैकलिंक्स से छुटकारा पाने के लिए हम क्या कर रहे हैं: NHibernate HiLo जनरेटर का उपयोग करें। इस तरह, NHibernate में हमेशा आपके आईडी/बच्चे संबंधों को डालने की आवश्यकता होती है।

< 3!

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

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