के साथ बाल संस्थाओं को बनाने का उचित तरीका मैं डीडीडी दुनिया के लिए काफी नया हूं और इसके बारे में कुछ किताबें पढ़ने के बाद (उनके बीच इवांस डीडीडी) मैं इंटरनेट पर अपने प्रश्न का उत्तर नहीं ढूंढ पाया: उचित तरीका क्या है डीडीडी के साथ बाल संस्थाओं का निर्माण? आप देखते हैं, इंटरनेट पर बहुत सारी जानकारी कुछ सरल स्तर पर चलती है। लेकिन विवरण में शैतान और सादगी के लिए वे हमेशा दर्जनों डीडीडी नमूने में छोड़े जाते हैं।डीडीडी
मैं स्टैक ओवरफ्लो पर सिमिलियर प्रश्न पर my own answer से आ रहा हूं। मैं इस समस्या पर अपनी दृष्टि से पूरी तरह से संतुष्ट नहीं हूं इसलिए मैंने सोचा कि मुझे इस मामले पर विस्तार करने की जरूरत है।
उदाहरण के लिए, मुझे साधारण मॉडल बनाने की ज़रूरत है जो कार नामकरण का प्रतिनिधित्व करती है: कंपनी, मॉडल और संशोधन (उदाहरण के लिए, निसान टीना 2012 - वह "निसान" कंपनी, "टीना" मॉडल और "2012" संशोधन होगी)।
मॉडल मैं इस तरह दिखता है बनाना चाहते हैं स्केच:
CarsCompany
{
Name
(child entities) Models
}
CarsModel
{
(parent entity) Company
Name
(child entities) Modifications
}
CarsModification
{
(parent entity) Model
Name
}
तो, अब मैं कोड बनाने की आवश्यकता है। मैं सी # को भाषा और एनएचबीनेटनेट को ओआरएम के रूप में उपयोग करूंगा। यह महत्वपूर्ण है और आम तौर पर इंटरनेट पर विशाल डीडीडी नमूने में नहीं दिखाया जाता है।
पहला दृष्टिकोण।
मैं कारखाने के तरीकों के माध्यम से विशिष्ट वस्तु निर्माण के साथ सरल दृष्टिकोण से शुरू करूंगा।
using (var tx = session.BeginTransaction())
{
var company = CarsCompany.Create ("Nissan");
var model = CarsModel.Create (company, "Tiana");
company.AddModel (model);
// (model.Company == company) is true
// but (company.Models.Contains (model)) is false
var modification = CarsModification.Create (model, "2012");
model.AddModification (modification);
// (modification.Model == model) is true
// but (model.Modifications.Contains (modification)) is false
session.Persist (company);
tx.Commit();
}
के बाद लेन-देन के लिए प्रतिबद्ध है और सत्र प्लावित है, ORM करेंगे:
public class CarsCompany
{
public virtual string Name { get; protected set; }
public virtual IEnumerable<CarsModel> Models { get { return new ImmutableSet<CarsModel> (this._models); } }
private readonly ISet<CarsModel> _models = new HashedSet<CarsModel>();
protected CarsCompany()
{
}
public static CarsCompany Create (string name)
{
if (string.IsNullOrEmpty (name))
throw new ArgumentException ("Invalid name specified.");
return new CarsCompany
{
Name = name
};
}
public void AddModel (CarsModel model)
{
if (model == null)
throw new ArgumentException ("Model is not specified.");
this._models.Add (model);
}
}
public class CarsModel
{
public virtual CarsCompany Company { get; protected set; }
public virtual string Name { get; protected set; }
public virtual IEnumerable<CarsModification> Modifications { get { return new ImmutableSet<CarsModification> (this._modifications); } }
private readonly ISet<CarsModification> _modifications = new HashedSet<CarsModification>();
protected CarsModel()
{
}
public static CarsModel Create (CarsCompany company, string name)
{
if (company == null)
throw new ArgumentException ("Company is not specified.");
if (string.IsNullOrEmpty (name))
throw new ArgumentException ("Invalid name specified.");
return new CarsModel
{
Company = company,
Name = name
};
}
public void AddModification (CarsModification modification)
{
if (modification == null)
throw new ArgumentException ("Modification is not specified.");
this._modifications.Add (modification);
}
}
public class CarsModification
{
public virtual CarsModel Model { get; protected set; }
public virtual string Name { get; protected set; }
protected CarsModification()
{
}
public static CarsModification Create (CarsModel model, string name)
{
if (model == null)
throw new ArgumentException ("Model is not specified.");
if (string.IsNullOrEmpty (name))
throw new ArgumentException ("Invalid name specified.");
return new CarsModification
{
Model = model,
Name = name
};
}
}
इस दृष्टिकोण के बारे में बुरी बात मॉडल की है कि सृष्टि के माता पिता मॉडल संग्रह में जोड़ने से नहीं करता है सही ढंग से डेटाबेस में सभी लिखें और अगली बार जब हम उस कंपनी को लोड करेंगे तो इसका मॉडल संग्रह सही ढंग से हमारे मॉडल को रखेगा। वही संशोधन में जाता है। तो यह दृष्टिकोण हमारी मूल इकाई को असंगत स्थिति में छोड़ देता है जब तक कि इसे डेटाबेस से पुनः लोड नहीं किया जाता है। नही जाओ।
दूसरा दृष्टिकोण।
इस बार हम अन्य वर्गों के संरक्षित गुणों को स्थापित करने की समस्या को हल करने के लिए भाषा विशिष्ट विकल्प का उपयोग करेंगे - अर्थात हम दोनों सेटर्स और कन्स्ट्रक्टर पर "संरक्षित आंतरिक" संशोधक का उपयोग करेंगे।
public class CarsCompany
{
public virtual string Name { get; protected set; }
public virtual IEnumerable<CarsModel> Models { get { return new ImmutableSet<CarsModel> (this._models); } }
private readonly ISet<CarsModel> _models = new HashedSet<CarsModel>();
protected CarsCompany()
{
}
public static CarsCompany Create (string name)
{
if (string.IsNullOrEmpty (name))
throw new ArgumentException ("Invalid name specified.");
return new CarsCompany
{
Name = name
};
}
public CarsModel AddModel (string name)
{
if (string.IsNullOrEmpty (name))
throw new ArgumentException ("Invalid name specified.");
var model = new CarsModel
{
Company = this,
Name = name
};
this._models.Add (model);
return model;
}
}
public class CarsModel
{
public virtual CarsCompany Company { get; protected internal set; }
public virtual string Name { get; protected internal set; }
public virtual IEnumerable<CarsModification> Modifications { get { return new ImmutableSet<CarsModification> (this._modifications); } }
private readonly ISet<CarsModification> _modifications = new HashedSet<CarsModification>();
protected internal CarsModel()
{
}
public CarsModification AddModification (string name)
{
if (string.IsNullOrEmpty (name))
throw new ArgumentException ("Invalid name specified.");
var modification = new CarsModification
{
Model = this,
Name = name
};
this._modifications.Add (modification);
return modification;
}
}
public class CarsModification
{
public virtual CarsModel Model { get; protected internal set; }
public virtual string Name { get; protected internal set; }
protected internal CarsModification()
{
}
}
...
using (var tx = session.BeginTransaction())
{
var company = CarsCompany.Create ("Nissan");
var model = company.AddModel ("Tiana");
var modification = model.AddModification ("2011");
session.Persist (company);
tx.Commit();
}
इस बार प्रत्येक इकाई निर्माण लगातार राज्य में माता-पिता और बाल इकाई दोनों को छोड़ देता है। लेकिन बाल इकाई राज्य की वैधता मूल इकाई (AddModel
और AddModification
विधियों में लीक हुई) में लीक हुई। चूंकि मैं डीडीडी में कहीं भी विशेषज्ञ नहीं हूं, मुझे यकीन नहीं है कि यह ठीक है या नहीं। यह भविष्य में और अधिक समस्याएं पैदा कर सकता है जब बच्चे संस्थाओं को गुणों के माध्यम से बस सेट नहीं किया जा सकता है और पास किए गए पैरामीटर के आधार पर कुछ राज्य स्थापित करने के लिए अधिक जटिल कार्य की आवश्यकता होती है जो संपत्ति को पैरामीटर मान निर्दिष्ट करती है। मैं इस धारणा के तहत था कि जहां भी संभव हो, उस इकाई के अंदर इकाई के बारे में तर्क को ध्यान में रखना चाहिए। मेरे लिए यह दृष्टिकोण मूल वस्तु को किसी प्रकार की इकाई & फैक्टरी हाइब्रिड में बदल देता है।
तीसरा दृष्टिकोण।
ठीक है, हम अभिभावक-बाल संबंध बनाए रखने की जिम्मेदारियों को उलटा कर देंगे।
public class CarsCompany
{
public virtual string Name { get; protected set; }
public virtual IEnumerable<CarsModel> Models { get { return new ImmutableSet<CarsModel> (this._models); } }
private readonly ISet<CarsModel> _models = new HashedSet<CarsModel>();
protected CarsCompany()
{
}
public static CarsCompany Create (string name)
{
if (string.IsNullOrEmpty (name))
throw new ArgumentException ("Invalid name specified.");
return new CarsCompany
{
Name = name
};
}
protected internal void AddModel (CarsModel model)
{
this._models.Add (model);
}
}
public class CarsModel
{
public virtual CarsCompany Company { get; protected set; }
public virtual string Name { get; protected set; }
public virtual IEnumerable<CarsModification> Modifications { get { return new ImmutableSet<CarsModification> (this._modifications); } }
private readonly ISet<CarsModification> _modifications = new HashedSet<CarsModification>();
protected CarsModel()
{
}
public static CarsModel Create (CarsCompany company, string name)
{
if (company == null)
throw new ArgumentException ("Company is not specified.");
if (string.IsNullOrEmpty (name))
throw new ArgumentException ("Invalid name specified.");
var model = new CarsModel
{
Company = company,
Name = name
};
model.Company.AddModel (model);
return model;
}
protected internal void AddModification (CarsModification modification)
{
this._modifications.Add (modification);
}
}
public class CarsModification
{
public virtual CarsModel Model { get; protected set; }
public virtual string Name { get; protected set; }
protected CarsModification()
{
}
public static CarsModification Create (CarsModel model, string name)
{
if (model == null)
throw new ArgumentException ("Model is not specified.");
if (string.IsNullOrEmpty (name))
throw new ArgumentException ("Invalid name specified.");
var modification = new CarsModification
{
Model = model,
Name = name
};
modification.Model.AddModification (modification);
return modification;
}
}
...
using (var tx = session.BeginTransaction())
{
var company = CarsCompany.Create ("Nissan");
var model = CarsModel.Create (company, "Tiana");
var modification = CarsModification.Create (model, "2011");
session.Persist (company);
tx.Commit();
}
यह दृष्टिकोण इसी संस्थाओं के अंदर सभी मान्यता/निर्माण तर्क हो गया और अगर यह अच्छा है या बुरा है मैं नहीं जानता, लेकिन कारखाना विधि हम परोक्ष पैरेंट ऑब्जेक्ट बच्चों संग्रह में जोड़ने के साथ वस्तु की सरल निर्माण से । लेनदेन प्रतिबद्धता और सत्र फ्लश के बाद डेटाबेस में 3 प्रविष्टियां होंगी, भले ही मैंने कभी भी अपने कोड में कुछ "एड" कमांड नहीं लिखा था। मुझे नहीं पता शायद यह सिर्फ मुझे और डीडीडी दुनिया के बाहर मेरा विशाल अनुभव है, लेकिन अब यह थोड़ा अप्राकृतिक लगता है।
तो, डीडीडी के साथ बाल संस्थाओं को जोड़ने का सबसे सही तरीका क्या है?
मैं सभी कोड उदाहरणों को हटा सकता हूं और इस पूरे प्रश्न को समझने में बहुत कठिन बना सकता हूं - लेकिन मुझे नहीं लगता कि यह समुदाय की मदद करेगा। मुझे पता नहीं था कि एसओ जटिल प्रश्नों के लिए नहीं है। –
पूरा प्रश्न (कोड के साथ या बिना) यहां अनुचित है। जैसा कि मैंने कहा, यह चर्चा के लिए पूछता है। मेरे द्वारा पोस्ट किए गए लिंक पढ़ें। मैं एक और प्रदान कर सकता हूं: [कोई चर्चा बोर्ड या मंच नहीं] (http://meta.stackexchange.com/a/128550/172661)। जैसा कि मैंने पहले कहा था, यह साइट ** स्पष्ट, संक्षिप्त प्रश्नों के लिए है जिसका उत्तर बिना किसी चर्चा के किया जा सकता है **। चूंकि आपका पूरा प्रश्न "सबसे सही तरीके" पर चर्चा करने और "विपक्षी [एसपी]" (जो यहां भी उचित नहीं है) पर चर्चा करने के बारे में है, यह यहां उचित नहीं है। –
मैं बहुत अधिक ठोस सवाल पूछ रहा हूं और इसके लिए एक विशेष जवाब के लिए इंतजार कर रहा हूं। मेरे उदाहरणों के साथ मैं केवल इस मामले में किए गए अनुसंधान प्रयासों को दिखाता हूं। मुझे किसी भी चर्चा की आवश्यकता नहीं है - मुझे स्पष्ट जवाब की आवश्यकता है कि यह सही तरीके से कैसे करें। सिर्फ इसलिए कि आप इस प्रश्न का उत्तर नहीं जानते हैं इसका मतलब यह नहीं है कि इसकी चर्चा प्रकृति है। डीडीडी दुनिया कई पैटर्न का उपयोग करती है और मैं मुझे यह इंगित करने के लिए कह रहा हूं कि मुझे इस विशेष समस्या को हल करने के लिए आवेदन करना चाहिए। –