6

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

दो उदाहरण संस्थाओं लें:

public class Ticket 
{ 
    public virtual int Id { get; set; } 
    public virtual string Title { get; set; } 
    public virtual string ServiceId { get; set; } 
    public virtual Service Service { get; set; } 
} 

public class Service 
{ 
    public virtual string Id { get; set; } 
} 

मैं टिकट का एक नया उदाहरण बनाने के लिए सक्षम होना चाहते हैं और निम्नलिखित साधनों का उपयोग यह करने के लिए एक सेवा आवंटित (मान लेते हैं कि संबद्ध सेवा तालिका में पहले से मौजूद है):

Ticket ticket = new Ticket() { 
    Title = "Problem with MS Word", 
    ServiceId = "Microsoft Word 2012" 
}; 

मुझे क्या करना नहीं चाहते हैं निम्नलिखित है:

Ticket ticket = new Ticket() { 
    Title = "Problem with MS Word", 
    Service = Session.Load<Service>("Microsoft Word 2012") 
}; 

मैं इस के लिए वैध कारण है, और इस तरह मैं इस इकाई की रूपरेखा में किया जा सकता है, लेकिन मैं वास्तव में कैसे धाराप्रवाह NHibernate में एक ही बात को प्राप्त करने के लिए के रूप में स्टम्प्ड हूँ कहा है। मेरी मैपिंग्स वर्तमान में इस तरह दिखती हैं:

public class TicketMapping : ClassMap<Ticket> 
{ 
    public TicketMapping() 
    { 
     Id(m => m.Id); 
     Map(m => m.Title).Column("Title"); 
     Map(m => m.ServiceId).Column("ServiceId"); 
     HasOne(m => m.Service).ForeignKey("ServiceId"); 

     Schema("dbo"); 
     Table("Tickets"); 
    } 
} 

public class ServiceMapping : ClassMap<Service> 
{ 
    public ServiceMapping() 
    { 
     Id(m => m.Id); 

     Schema("dbo"); 
     Table("Services"); 
    } 
} 

किसी भी मदद की हमेशा सराहना की जाती है!


बस जे के लिए एक त्वरित संपादित करें - कारण मैं अपने तत्व Session.Load नहीं करना चाहता है, क्योंकि मैं अपनी प्रस्तुति परत (MVC 3) NHibernate के बारे में जानते हुए भी कुछ भी नहीं करना चाहते हैं - इसलिए मैं मैं एक भंडार पैटर्न का उपयोग कर रहा हूं और नियंत्रक में एक एकल भंडार इंजेक्शन कर रहा हूं। उदाहरण के लिए, मैं एक TicketRepository जो निम्नलिखित अनुबंध का पालन करता है होगा

public interface IRepository<T> 
{ 
    T GetById(object id); 
    void Create(T entity); 
    void Update(T entity); 
    void Delete(T entity); 
} 

मैं एक ServiceRepository इंजेक्षन करने के लिए भी बस के लिए सेवा के लिए एक संदर्भ पाने के लिए नहीं करना चाहते हैं टिकट

+1

क्या आप 'सत्र' लोड 'का उपयोग नहीं करना चाहते हैं, इसके वैध कारणों पर विस्तार कर सकते हैं? – Jay

+1

@ जे, टेरिक के कारण से निश्चित नहीं है ... लेकिन यह कभी-कभी सहेजने से पहले आपके पास पहले से मौजूद कुंजी को संदर्भित करने में सक्षम होने के लिए ऑब्जेक्ट को लोड करने के लिए हास्यास्पद ओवरहेड हो सकता है, IMHO। हमारे पिछले प्रोजेक्ट पर सख्त एसएलए था जहां हमें एफके समर्थन से पहले एंटीटी फ्रेमवर्क पर एक ही काम करना था। –

+0

@Jay ने कारणों से मेरी पोस्ट अपडेट की है। इसके अलावा, केविन एक अच्छा मुद्दा बनाते हैं, मैं इस संबद्ध के लिए किसी अन्य इकाई को लोड करने के अतिरिक्त ओवरहेड नहीं चाहता हूं। –

उत्तर

3

जिस तरह से मैं इसे देखता हूं आप वास्तव में सत्र का उपयोग करने से बच नहीं सकते हैं। लोड (आईडी) NHibernate का उपयोग करते समय। जैसा कि टिप्पणियों में उल्लिखित है, यह डेटाबेस को हिट नहीं करेगा, बस आईडी के साथ प्रॉक्सी ऑब्जेक्ट बनाएं।

कुछ संभव विकल्प:

  1. एक दूसरे सामान्य भंडार (ServiceRepository) नियंत्रक में सम्मिलित करें। मैं वास्तव में इसके साथ कोई समस्या नहीं देख सकता, लेकिन किसी कारण से आप इससे बचना चाहते हैं। आप जेनेरिक इंटरफ़ेस में LoadById विधि जोड़ सकते हैं और एनएच और ईएफ (या अन्य) के लिए प्रत्येक कार्यान्वयन में अलग-अलग कार्यान्वित कर सकते हैं। ईएफ में यह तरीका है कि विधि GetById की तरह काम कर सकती है, जबकि एनएच में यह सत्र को कॉल करता है। लोड
  2. एआर (कुल रूट) के लिए एक गैर-जेनेरिक भंडार लागू करें जो इस मामले में टिकट होगा। इसमें सेवा और टिकट को लोड करने के लिए विशिष्ट विधियां हो सकती हैं।
  3. दो भंडारों के शीर्ष पर एक और अमूर्त कार्यान्वयन और विकल्प 1 में दो भंडारों के बजाय नियंत्रक में इंजेक्ट करें। यह एफ हो सकता है।पूर्व में उल्लिखित एक अज्ञात अज्ञात यूनिटऑफवर्क हो: Persistance ignorant UoW, या किसी प्रकार की एप्लिकेशन सेवा जो टिकटों, या टिकट फैक्ट्री के निर्माण को व्यवस्थित करती है।

3 विकल्पों में से, विकल्प 1 शायद सबसे सरल है, जबकि 3 सड़क के नीचे बेहतर अमूर्तता और अधिक रखरखाव प्रदान कर सकता है।

+0

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

+0

मैं अपनी विदेशी चाबियों को वस्तुओं के बजाय इनट्स में परिवर्तित करने के विचार के आसपास फेंक रहा हूं क्योंकि मैं प्रत्येक सम्मिलित या अद्यतन पर प्रत्येक लिंक किए गए ऑब्जेक्ट के लिए डीबी को हिट नहीं करना चाहता था ... जब तक कि मैं इस प्रश्न पर नहीं आया और इसके बारे में सीखा Session.Load()। सरल संचालन के लिए निहितार्थ लॉग परिणामों की तुलना करने के बाद - वाह! बड़ी बचत! धन्यवाद! – Brett

0

आप एक चाल का उपयोग कर सकते हैं। अपना कोड साफ रखने के लिए।

यह एनएच का एक मुद्दा है, आपको इसे एनएच रिपोजिटरीज में समाधान लागू करना होगा, इसलिए मैं इसे इस तरह हल करता हूं।

से पहले जोड़े या अपडेट

if (!string.IsNullOrEmpty(ServiceId) && Service == null) 
{ 
    Service = new Service{ Id = ServiceId }; 
} 

सामान्य भंडार काम ...

मैं इसे परीक्षण करने और काम करते हैं। आपका आर्किटेक्चर अभी भी ओआरएम निर्णयों को साफ करता है

+0

मान लीजिए कि क्या सेवा वर्ग में कई फ़ील्ड हैं, तो उस स्थिति में हमें यहां सभी फ़ील्ड असाइन करने की आवश्यकता है? क्योंकि मुझे एक ही समस्या का सामना करना पड़ रहा है .. – jkyadav

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

  • कोई संबंधित समस्या नहीं^_^