8

मैं है निम्नलिखित 2 वर्गों:धाराप्रवाह NHibernate एक-से-अनेक मानचित्रण

विज्ञापन

public virtual int Id { get; set; 
public virtual IList<AdvertImage> AdvertImages { get; set; } 

AdvertImage

public virtual int Id { get; set; } 
public virtual string Filename { get; set; 
public virtual Advert Advert { get; set; } 

डीबी में, मेरा AdvertImages टेबल है एफके 'एडवर्टर आईडी' जो विज्ञापन तालिका से संबंधित है जिसमें 'आईडी' का पीके है।

यह एक-से-कई मैपिंग है, उस विज्ञापन में कई छवियां हो सकती हैं।

मेरे धाराप्रवाह NHibernate मैपिंग (संक्षिप्तता के लिए संपादित) कर रहे हैं:

AdvertMap

Id(x => x.Id) 
    .GeneratedBy.Identity(); 
... 
HasMany(x => x.AdvertImages) 
    .KeyColumn("AdvertId") 
    .Inverse(); 
... 
Table("Adverts"); 

AdvertImageMap

Id(x => x.Id) 
    .GeneratedBy.Identity(); 
... 
References(x => x.Advert) 
    .Column("AdvertId"); 
... 
Table("AdvertImages"); 

मैं कोड में Advert का एक नया उदाहरण बनाने रहा हूँ, फिर AdvertImages प्रोपे पॉप्युलेटिंग List<AdvertImage> के साथ आरटीआई (विज्ञापन का)।

जब मैं डीबी में अपने Advert ऑब्जेक्ट को जारी रखने के लिए जाता हूं, तो मैं विज्ञापन छवियों को उनके विज्ञापन छवि तालिका में डालना चाहता हूं, लेकिन 2 तालिकाओं के बीच संबंधों के कारण, मुझे विज्ञापन सम्मिलन पहले होने की आवश्यकता है, इसलिए पीके आईडी उत्पन्न होता है, जिसे तब विज्ञापन छवि तालिका में डाला जा सकता है। (जब मैं AdvertImage की अपनी सूची बनाता हूं, तो मैं फ़ाइल नाम की संपत्ति को पॉप्युलेट कर रहा हूं, लेकिन स्पष्ट रूप से उस चरण में नया विज्ञापन नहीं है, इसलिए जब विज्ञापन डीबी पर जारी रहता है तो पॉप्युलेट होना चाहिए)।

मैंने अलग-अलग इनवर्क्स() और कैस्केड सेटिंग्स के साथ प्रयोग करने का प्रयास किया है लेकिन अभी तक सफल नहीं हुआ है। क्या कोई मदद कर सकता है?

उत्तर

10

आप झरना करने के लिए अपने Advert मानचित्रण को बदलने की जरूरत:

Id(x => x.Id) 
    .GeneratedBy.Identity(); 

HasMany(x => x.AdvertImages) 
    .KeyColumn("AdvertId") 
    .Inverse() 
    .Cascade.AllDeleteOrphan(); 

Table("Adverts"); 

फिर आप और एक Advert वस्तु लागू करने के लिए इस तरह कुछ करने के लिए सक्षम होना चाहिए

यहाँ कुछ इसी तरह के सवाल है कि मदद कर सकता है है यह बच्चे AdvertImage है।

Advert newAdvert = new Advert(); 
AdvertImage newImage = new AdvertImage(); 
newImage.Advert = newAdvert; 
newAdvert.AdvertImages.Add(newImage); 

using(NHibernate.ISession session = SessionFactory.GetCurrentSession()) 
{ 
    using (NHibernate.ITransaction tran = session.BeginTransaction()) 
    { 
     session.Save(newAdvert); 
     tran.Commit(); 
    } 
} 

मेरे संस्थाओं आमतौर पर जोड़े और इस तरह कई रिश्तों को द्विदिश एक के लिए तरीके निकालें होते हैं:

public class Advert 
{ 
    public virtual IList<AdvertImage> AdvertImages { get; set; } 

    public virtual void AddImage(AdvertImage newImage) 
    { 
     newImage.Advert = this; 
     AdvertImages.Add(newImage); 
    } 
} 
+0

धन्यवाद कोल डब्ल्यू, और अच्छी टिप और जोड़ें विधियों को फिर से हटाएं। – marcusstarnes

1

मेरे लिए क्या काम करता है आमतौर पर डीबी में नल की अनुमति देने के लिए विदेशी कुंजी कॉलम सेट करना है - यह आपका विज्ञापन आईडी कॉलम होगा, लेकिन मुझे यकीन नहीं है कि यह आपके मामले में काम करेगा, क्योंकि आप पहचान का उपयोग कर रहे हैं। एनएचबीरनेट क्या करता है सभी एक प्रश्न के साथ INSERT है और फिर मूल तालिका की सही आईडी पर बाल तालिका विदेशी कुंजी कॉलम अपडेट करता है। शायद यह आपके मामले में भी काम करेगा। Cascade insert on one-to-many with fluent NHibernate

+1

आपके द्वारा शामिल लिंक को कोई समझ नहीं आता क्योंकि इसका 'फ्लुएंट एनएचबर्ननेट' से कोई लेना देना नहीं है। – Komengem

+0

@ कॉमेन्जमंडिला हालांकि मेरे द्वारा लिंक किए गए प्रश्न का उत्तर फ्लुएंट एनएचबेर्नेट का उपयोग नहीं करता है, सवाल यह है। इसके अलावा, Fluent NHibernate यहां कुछ भी नया नहीं जोड़ता है। यह सिर्फ NHibernate मैपिंग के लिए एक और इंटरफ़ेस प्रदान करता है। एक बार जब आप समझते हैं कि मैपिंग कैसे काम करती है, तो आप इसे फ्लुएंट एनएचबर्ननेट, एक्सएमएल मैपिंग, कोड द्वारा मैपिंग पर लागू कर सकते हैं ... –

2

मैं एक ही मुद्दा था। मैंने विभिन्न प्रकार के मैपिंग की कोशिश करते समय थोड़ी देर बिताई।मैंने तब पाया कि मेरे मैपिंग ठीक थे और वास्तव में मुझे लेनदेन में अपना सत्र लपेटने और सत्र के बाद Commit() विधि का उपयोग करने की आवश्यकता थी। SavOrUpdate() विधि।

using(var session = sessionFactory.OpenSession()) 
using(var tx = session.BeginTransaction()) 
{ 
// execute code that uses the session 
tx.Commit(); 
} 
+0

धन्यवाद .. इस मुद्दे के आसपास खुदाई करने में काफी समय बचा –