2010-04-26 5 views
5

ठीक है, इसलिए कल मैंने अपने नवीनतम छोटे प्रोजेक्ट के साथ काम करने के लिए एनएचबीर्नेट और फ़्लुएंट हाइबरनेट के नवीनतम ट्रंक बिल्डों को प्रबंधित करने में कामयाब रहे। (मैं एक बग ट्रैकिंग एप्लिकेशन पर काम कर रहा हूं।) मैंने रिपोजिटरी पैटर्न का उपयोग करके एक अच्छी डेटा एक्सेस लेयर बनाई है।फ़्लुएंट हाइबरनेट के ऑटो मैपर को ट्यून कैसे करें?

मैंने फैसला किया कि मेरी संस्थाएं कुछ खास नहीं हैं, और यह भी कि ओआरएम की वर्तमान परिपक्वता के साथ, मैं डेटाबेस को हाथ से तैयार नहीं करना चाहता हूं। इसलिए, मैंने FluentNHibernate की ऑटो मैपिंग सुविधा का उपयोग NHibernate की "hbm2ddl.auto" प्रॉपर्टी सेट "बनाने" के साथ किया है।

यह वास्तव में एक आकर्षण की तरह काम करता है। मैंने अपने ऐप डोमेन की कॉन्फ़िगरेशन फ़ाइल में NHibernate कॉन्फ़िगरेशन डाला, इसे सेट अप किया, और इसके साथ खेलना शुरू कर दिया। (समय के लिए, मैंने केवल कुछ यूनिट परीक्षण बनाए हैं।) यह डेटाबेस में सभी तालिकाओं को बनाया गया है, और इसके लिए मुझे जो भी चाहिए। यह मेरे कई से कई रिश्तों को सही ढंग से मैप किया गया।

    डीबी में बनाए गए स्तंभों की
  • सभी अशक्त अनुमति देते हैं:

    हालांकि, वहाँ कुछ छोटे खामियों कर रहे हैं। मैं समझता हूं कि यह अनुमान नहीं लगा सकता कि कौन से गुणों को शून्य की अनुमति देनी चाहिए और जो नहीं करना चाहिए, लेकिन कम से कम मैं इसे बताना चाहता हूं कि इसे केवल उन प्रकारों के लिए शून्य की अनुमति देनी चाहिए जिनके लिए .NET में शून्य है (उदाहरण के लिए गैर। सुस्त मूल्य प्रकारों को शून्य की अनुमति नहीं देनी चाहिए)।

  • इसके द्वारा बनाए गए सभी nvarchar और varbinary कॉलम, 255 की डिफ़ॉल्ट लंबाई है। मैं उन्हें इसके बजाय अधिकतम पर रखना पसंद करूंगा।

क्या ऊपर दो सरल नियमों के बारे में ऑटो मैपर को बताने का कोई तरीका है?

यदि उत्तर नहीं है, तो क्या यह सही ढंग से काम करेगा यदि मैं इसे बनाए गए तालिकाओं को संशोधित करता हूं? (तो, अगर मैं कुछ स्तंभ सेट नहीं अशक्त की अनुमति देते हैं, और कुछ अन्य के लिए स्वीकृत सीमा बदलने के लिए, इसे सही ढंग से उन लोगों के साथ काम करेंगे के लिए?)

अंतिम संपादन: बिग जो कोई द्वारा गिरा और बाहर की मदद की के लिए धन्यवाद। फ्लुएंट के साथ मेरे सभी मुद्दों को हल किया गया है।

उत्तर

6

ऑटो मैपर काम करने के तरीके को बदलने के लिए आप ऑटो मैपिंग ओवरराइड का उपयोग कर सकते हैं, और आप सम्मेलन को भी परिभाषित कर सकते हैं, जिसका उपयोग ऑटो मैपर द्वारा किया जाएगा।

var mappings = new AutoPersistenceModel(); 
mappings.Conventions.Setup(s => s.Add<ColumnNullabilityConvention>()); 
mappings.UseOverridesFromAssemblyOf<AssemblyName>(); 

// This convention will set all properties to be not nullable 

public class ColumnNullabilityConvention: IPropertyConvention, IPropertyConventionAcceptance 
{ 
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria) 
    { 
     criteria.Expect(x => x.Nullable, Is.Not.Set); 
    } 

    public void Apply(IPropertyInstance instance) 
    { 
     instance.Not.Nullable(); 
    } 
} 

// This override will change "string" to use "text" instead of "varchar(255)". 
// Also set the property to be not nullable 

public class SomeOverrideInTheSameAssembly : IAutoMappingOverride<TypeName> 
{ 
    public void Override(AutoMapping<TypeName> mapping) 
    { 
     mapping.Map(x => x.Property).CustomType("StringClob").CustomSqlType("text"); 
     mapping.Map(x => x.Property).Not.Nullable(); 
    } 
}  

चेक अधिक उदाहरण के लिए इन लिंक:

+0

बहुत बहुत धन्यवाद! मैं इसे निम्नलिखित कोड के साथ काम करने में कामयाब रहा: दृढ़ता मॉडल। कॉन्वेंटन। जोड़ें (कन्वेंशनबिल्डर। प्रॉपर्टी। हमेशा (x => x.Length (16000))); हालांकि यह थोड़ा हैकी है, क्योंकि SQL सर्वर में, 16000 इसे MAX पर सेट करेगा, लेकिन यह अन्य डेटाबेस सर्वर के लिए अच्छा नहीं हो सकता है। क्या ऐसा करने का एक सामान्य तरीका है? – Venemo

+0

वास्तव में नहीं। आम तौर पर आपको इसे "स्ट्रिंगक्लब" कस्टमटाइप पर सेट करना चाहिए, क्योंकि इसका मतलब एनएचबीर्नेट को होना चाहिए कि यह 'टेक्स्ट' प्रकार है, लेकिन यहां तक ​​कि कुछ एनएचबीरनेट डेटाबेस प्रदाता (जैसे PostgreSQL) इसे अवहेलना करेंगे। यही कारण है कि उदाहरण के लिए मेरे ओवरराइड उदाहरण में मैंने कस्टम टेक्स्ट और कस्टमस्क्लट घोषणा दोनों का उपयोग "टेक्स्ट" पर सेट करने के लिए किया है। वैकल्पिक रूप से यदि आप नीचे डेटाबेस स्कीमा बदलते हैं तो NHibernate वास्तव में परवाह नहीं करेगा कि यह वर्चर है या कुछ बड़ा (टेक्स्ट, ब्लॉब, आदि) है। लेकिन यह बहुत स्पष्ट चीजों के कारण या तो एक अच्छा समाधान नहीं है। – SztupY

+0

ठीक है, मैं इसे छोड़ दूंगा क्योंकि यह समय के लिए है। बीटीडब्ल्यू, यहां एक और हंगरी देखना अच्छा लगता है। :) – Venemo

1

यह व्यापक रूप से ज्ञात नहीं है, लेकिन आप अपने कॉन्फ़िगर कोड में मैपिंग अनुभाग से कई सम्मेलनों को सेट कर सकते हैं उदा।

Fluently.Configure() 
    .Database(/* database config */) 
    .Mappings(m => 
    { 
    m.FluentMappings 
     .AddFromAssemblyOf<Entity>() 
     .Conventions.Add(PrimaryKey.Name.Is(x => "ID")); 
    }) 

प्राथमिक कुंजी सम्मेलन सेट करने के लिए।

संपादित करें: क्या PrimaryKey सम्मेलन करता है के स्पष्टीकरण:

PrimaryKey सम्मेलन निर्दिष्ट क्या प्राथमिक कुंजी के स्तंभ, है नहीं संपत्ति किया जाता है। संपत्ति की खोज करना एक शुद्ध ऑटोमैपिंग व्यायाम है, जबकि सम्मेलन क्लासमैप्स और ऑटोमैपिंग पर लागू होते हैं। - जेम्स ग्रेगरी

यह (विकी से) समर्थित सम्मेलनों की सूची है:

Table.Is(x => x.EntityType.Name + "Table") 
PrimaryKey.Name.Is(x => "ID") 
AutoImport.Never() 
DefaultAccess.Field() 
DefaultCascade.All() 
DefaultLazy.Always() 
DynamicInsert.AlwaysTrue() 
DynamicUpdate.AlwaysTrue() 
OptimisticLock.Is(x => x.Dirty()) 
Cache.Is(x => x.AsReadOnly()) 
ForeignKey.EndsWith("ID") 

FNH विकि पर The Simplest Conventions अनुभाग देखें।

+0

आपके उत्तर के लिए बहुत बहुत धन्यवाद। मैं इसे कुछ कस्टम सम्मेलनों का उपयोग करके काम करने में कामयाब रहा। हालांकि, विकी को देखने के बाद, एक और चीज है जो मुझे खराब करती है। मैं ठीक से काम करने के लिए PrimaryKey.Name.Is (x => "आईडी") नहीं प्राप्त कर सकता। – Venemo

+1

क्षमा करें, मैंने कभी प्राथमिक प्राथमिक सम्मेलन का उपयोग नहीं किया है - मैंने सिर्फ विकी से उदाहरण की प्रतिलिपि बनाई है। एक बग हो सकता है। मेरा सुझाव है कि आप एफएनएच समर्थन मंच पर एक प्रश्न पोस्ट करें - http://support.fluentnhibernate.org/ –

+0

करेंगे, धन्यवाद। – Venemo

3

आपके आईडी की समस्याओं के लिए, आपको FindIdentity सेटिंग बदलने की आवश्यकता है। यह automapping wiki page में शामिल है, हालांकि संक्षेप में यद्यपि।

वह कुछ इस तरह जाना चाहिए:

AutoMap.AssemblyOf<Entity>() // your usual setup 
    .Setup(s => 
    { 
    s.FindIdentity = m => m.Name == "ID"; 
    }); 

यह क्या करता है automapper हिदायत जब आईडी खोजने की कोशिश कर अपने नए लैम्ब्डा (m => m.Name == "ID") का प्रयोग है। m संपत्ति/सदस्य है, और यह लैम्ब्डा प्रत्येक इकाई पर प्रत्येक संपत्ति के लिए बुलाया जाता है; जो भी आप सच के लिए वापस आते हैं वह आईडी है।

+0

@ जेम्स - तो प्राथमिक के सम्मेलन उनके लिए क्यों काम नहीं किया? एफएनएच में बग? विधि का दुरुपयोग? –

+0

'प्राथमिक कुंजी' सम्मेलन का उपयोग यह निर्दिष्ट करने के लिए किया जाता है कि प्राथमिक कुंजी का * कॉलम * संपत्ति नहीं है। संपत्ति की खोज करना एक शुद्ध स्वैपिंग व्यायाम है, जबकि कक्षाओं और ऑटोमैपिंग पर सम्मेलन लागू होते हैं। –

+0

स्पष्टीकरण के लिए धन्यवाद - अनुमान लगाएं कि नाम वेनेमो और मुझे बेवकूफ़ बनाते हैं। मैं अपना जवाब संपादित करूंगा। –

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