2009-06-16 10 views
12

मेरी सेवाओं में संदर्भ डेटा के लिए उपयोग करने के लिए "सर्वोत्तम" पैटर्न के संबंध में प्रतिक्रिया/विकल्प/टिप्पणियां हल करना।डब्ल्यूसीएफ डेटा अनुबंध और संदर्भ इकाई डेटा?

संदर्भ डेटा से मेरा क्या मतलब है?

चलिए नॉर्थविंड का उदाहरण के रूप में उपयोग करते हैं। एक आदेश डेटाबेस में किसी ग्राहक से संबंधित है। जब मैं अपने ऑर्डर सेवा को कार्यान्वित करता हूं, तो कुछ मामलों में मैं एक "पूर्ण" ग्राहक को आदेश से और अन्य मामलों में संदर्भ चाहता हूं, जब मैं केवल ग्राहक के लिए संदर्भ चाहता हूं (उदाहरण के लिए एक कुंजी/मूल्य जोड़ी)।

उदाहरण के लिए, यदि मैं GetAllOrders() कर रहा था, तो मैं पूरी तरह से भरे हुए ऑर्डर को वापस नहीं करना चाहता, मैं प्रत्येक ऑर्डर के ग्राहक के लिए केवल संदर्भ डेटा के साथ ऑर्डर का हल्का संस्करण वापस करना चाहता हूं। अगर मैंने GetOrder() विधि की है, हालांकि, मैं शायद ग्राहक विवरण भरना चाहता हूं क्योंकि इस विधि के उपभोक्ता को इसकी आवश्यकता हो सकती है। ऐसी अन्य स्थितियां हो सकती हैं जहां मैं पूछना चाहूंगा कि कुछ विवरण कॉल के दौरान ग्राहक विवरण भर जाएंगे, लेकिन दूसरों के लिए छोड़ दिया जाएगा।

यहाँ है कि मैं क्या लेकर आए हैं:

[DataContract] 
public OrderDTO 
{ 
    [DataMember(Required)] 
    public CustomerDTO; 

    //etc.. 
} 

[DataContract] 
public CustomerDTO 
{ 
    [DataMember(Required)] 
    public ReferenceInfo ReferenceInfo; 

    [DataMember(Optional)] 
    public CustomerInfo CustomerInfo; 
} 

[DataContract] 
public ReferenceInfo 
{ 
    [DataMember(Required)] 
    public string Key; 

    [DataMember(Required)] 
    public string Value; 
} 

[DataContract] 
public CustomerInfo 
{ 
    [DataMember(Required)] 
    public string CustomerID; 

    [DataMember(Required)] 
    public string Name; 

    //etc.... 
} 

सोच है कि यहाँ के बाद से ReferenceInfo (जो एक सामान्य की/मान जोड़ी है) हमेशा CustomerDTO में आवश्यक है, मैं हमेशा ReferenceInfo होगा है । यदि आवश्यक हो तो बाद में ग्राहक विवरण प्राप्त करने के लिए मुझे पर्याप्त जानकारी मिलती है। ग्राहक डीटीओ होने के नकारात्मक पक्ष में रेफरेंसइन्फो की आवश्यकता है कि जब मैं पूर्ण ग्राहक डीटीओ (यानि कस्टमरइन्फो भरने के साथ) प्राप्त कर रहा हूं तो यह अधिक हो सकता है, लेकिन कम से कम मुझे संदर्भ जानकारी की गारंटी है।

क्या कोई अन्य पैटर्न या ढांचा टुकड़ा है जिसका उपयोग मैं इस परिदृश्य/कार्यान्वयन "क्लीनर" बनाने के लिए कर सकता हूं?

कारण मैं पूछता हूं कि हालांकि हम नॉर्थविंड में हमेशा एक पूर्ण ग्राहक डीटीओ वापस लौटने के लिए कह सकते हैं, जो सरल नॉर्थविंड स्थिति में ठीक काम कर सकता है। मेरे मामले में, मेरे पास एक ऑब्जेक्ट है जिसमें 25-50 फ़ील्ड हैं जो संदर्भ/लुकअप प्रकार डेटा हैं। कुछ अलग-अलग परिस्थितियों में दूसरों की तुलना में लोड करने के लिए अधिक महत्वपूर्ण हैं, लेकिन मैं इन संदर्भ प्रकारों की यथासंभव कम परिभाषाएं लेना चाहता हूं (ताकि मैं "डीटीओ रखरखाव नरक" में न जाऊं)।

राय? प्रतिक्रिया? टिप्पणियाँ?

धन्यवाद!

+0

FWIW ... मुझे लगता है कि लिंक से एसक्यूएल, इकाई फ्रेमवर्क, या एडीओ नहीं है।नेट डाटा सर्विसेज यहां मेरी मदद करेगी, क्योंकि मेरे पास 3 अलग-अलग सिस्टम हैं, सभी प्रतिनिधित्व करते हैं, अनिवार्य रूप से, एक ही डेटासेट। इन प्रणालियों को समेकित करने का यह पहला कदम है, या कम से कम बाहरी प्रणालियों के लिए इन तीन प्रणालियों से डेटा को अधिक सामान्य और लगातार तरीके से उपभोग करने में सक्षम होना चाहिए। – Brian

+0

क्या आप कृपया http://stackoverflow.com/questions/9483286/understanding-data-outside-of-service-soa का उत्तर दे सकते हैं? – Lijo

उत्तर

1

यह मेरे लिए एक जटिल समाधान की तरह लगता है। ऑर्डर डीटीओ कक्षा में केवल ग्राहक आईडी फ़ील्ड क्यों नहीं है और फिर एप्लिकेशन को रनटाइम पर निर्णय लेने दें कि क्या उसे ग्राहक डेटा की आवश्यकता है या नहीं। चूंकि इसमें ग्राहक आईडी है, इसलिए यह निर्णय लेने पर डेटा को नीचे खींच सकता है।

+0

मैं ग्राहक आईडी को ग्राहक डेटा प्राप्त करने की क्षमता का खुलासा करूंगा, लेकिन "चैट" इंटरफेस से बचने की कोशिश कर रहा हूं। – Brian

+0

"चैट" इंटरफ़ेस द्वारा मेरा क्या मतलब है इसका विस्तार करना। मान लीजिए कि मैं ग्रिड में GetAllOrders() के परिणाम प्रदर्शित करता हूं। ग्रिड में एक कॉलम "ग्राहक नाम" है। मैं ग्रिड में प्रदर्शित हर आदेश के लिए GetCustomer() को कॉल नहीं करना चाहता हूं। इसके अतिरिक्त, मैं अपने अनुबंध को तोड़ना नहीं चाहता हूं अगर कोई नई आवश्यकता बताती है कि ग्राहक नाम के अतिरिक्त हमें भी प्रदर्शित करना होगा, उदाहरण के लिए, ग्राहक फोन नंबर। मैं बस अपनी विधि कॉल को कुछ ऐसा करने में सक्षम होना चाहता हूं:
GetAllOrders (expandReference = true); नोट: सुनिश्चित नहीं है कि फोन नंबर वास्तव में नॉर्थविंड में है या नहीं। – Brian

+0

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

1

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

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

[DataContract] 
public OrderDTO 
{ 
    [DataMember(Required)] 
    public CustomerDTO Customer; 

    //in this case, I think consumers will need currency data, 
    //so I pass back a full currency item 
    [DataMember(Required)] 
    public Currency Currency; 

    //in this case, I think consumers are not likely to need full StateRegion data, 
    //so I pass back a "reference" to it 
    //User's can call a separate service method to get full details if needed, or 
    [DataMember(Required)] 
    public KeyValuePair ShipToStateRegion; 

    //etc.. 
} 


[DataContract] 
[KnownType(Currency)] 
public KeyValuePair 
{ 
    [DataMember(Required)] 
    public string Key; 

    [DataMember(Required)] 
    public string Value; 

    //enum consisting of all possible reference types, 
    //such as "Currency", "StateRegion", "Country", etc. 
    [DataMember(Required)] 
    public ReferenceType ReferenceType; 
} 


[DataContract] 
public Currency : KeyValuePair 
{ 
    [DataMember(Required)] 
    public decimal ExchangeRate; 

    [DataMember(Required)] 
    public DateTime ExchangeRateAsOfDate; 
} 


[DataContract] 
public CustomerDTO 
{ 
    [DataMember(Required)] 
    public string CustomerID; 

    [DataMember(Required)] 
    public string Name; 

    //etc.... 
} 

विचार? राय? टिप्पणियाँ?

+0

यह एक उचित समझौता की तरह लगता है, लेकिन जब तक आप यह समझते हैं कि गुणों का "सामान्य सबसेट" क्या होना चाहिए, तब तक ट्यूनिंग और ट्वीविंग के लिए तैयार रहें। और यदि यह परियोजना प्राथमिक रूप से रिपोर्टिंग या विश्लेषण उद्देश्यों के लिए है, तो हमेशा संभावना है कि एक सामान्य सबसेट नहीं होगा। और यह आपको फिर से कई धारावाहिकों की आवश्यकता के लिए वापस ले जाता है। – dthrasher

+0

@ ब्रायन- भले ही यह एक पुराना सवाल है, मैंने अमेज़ॅन को यह कैसे किया है इसके बारे में एक जवाब जोड़ा है, क्योंकि आप इसे उपयोगी पा सकते हैं। – RichardOD

2

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

एक बात जो मैं सोच रहा हूं वह यह है कि अगर हम सीख सकते हैं कि हमारी सेवाएं "गलत" स्तर पर डिज़ाइन की गई हैं। उदाहरण के लिए, क्या कभी ऐसा कोई उदाहरण है जहां हमें एक फुलथिंग को अलग करना चाहिए और केवल एक सरल टिंग पास करना चाहिए? अगर हम करते हैं, तो क्या इसका मतलब है कि हमने कुछ स्तर पर कुछ व्यापारिक तर्क को उचित रूप से रखा है?

+0

क्या यह आपके लिए काम करता है? मैं इस दृष्टिकोण की ओर अधिक इच्छुक हूं। – Jonn

1

हमें ऑब्जेक्ट-रिलेशनल मैपिंग में भी इस समस्या का सामना करना पड़ा है। ऐसी परिस्थितियां हैं जहां हम पूर्ण वस्तु और अन्य चाहते हैं जहां हम इसका संदर्भ चाहते हैं।

कठिनाई यह है कि खुद को वर्गों में क्रमबद्धता पाक द्वारा, datacontract पैटर्न विचार है कि वहाँ केवल एक सही तरीके से एक वस्तु को क्रमानुसार करने को लागू करता है। लेकिन ऐसे कई परिदृश्य हैं जहां आप आंशिक रूप से कक्षा और/या उसके बच्चे की वस्तुओं को क्रमबद्ध करना चाहते हैं।

आमतौर पर इसका मतलब है कि प्रत्येक वर्ग के लिए आपके पास एकाधिक डीटीओ होना चाहिए। उदाहरण के लिए, एक पूर्ण ग्राहक डीटीओ और एक ग्राहक रिफरेंस डीटीओ। फिर आपको अलग-अलग डीटीओ को ग्राहक डोमेन ऑब्जेक्ट पर मैप करने के तरीके बनाना होगा।

जैसा कि आप कल्पना कर सकते हैं, यह काम का एक टन है, इसमें से अधिकांश बहुत कठिन हैं।

+0

क्या आप कृपया http://stackoverflow.com/questions/9483286/understanding-data-outside-of-service-soa का उत्तर दे सकते हैं? – Lijo

1

वस्तुओं की संपत्ति के रूप में वस्तुओं का इलाज करने की एक और संभावना है। पूछताछ करते समय इच्छित गुणों को निर्दिष्ट करें, और आपको आवश्यक गुणों को वापस प्राप्त करें।

"लघु" संस्करण में दिखाने के लिए गुणों को बदलने के बाद कई राउंड ट्रिप की आवश्यकता नहीं होगी, आप एक समय में एक सेट के लिए सभी गुण प्राप्त कर सकते हैं (चतुर इंटरफेस से परहेज करते हैं), और आपको नहीं करना है यदि आप तय करते हैं कि आपको "लघु" संस्करण के लिए अलग-अलग गुणों की आवश्यकता है, तो अपने डेटा या ऑपरेशन अनुबंधों को संशोधित करें।

+0

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

+1

दोनों जरूरी नहीं हैं। अंतर्निहित कार्यान्वयन के रूप में एक संपत्ति बैग का उपयोग करते समय, आपके सार्वजनिक-पक्षीय एपीआई में स्थिर रूप से टाइप किए गए फ़ील्ड हो सकते हैं। ज्ञात स्थैतिक सामानों के लिए स्थिर गुणों को बनाए रखने के दौरान आप "फ़ील्ड" के गतिशील जोड़ की अनुमति देने के लिए बैग (प्रत्यक्ष या परोक्ष रूप से) का खुलासा भी कर सकते हैं। – kyoryu

+0

अधिक विशिष्ट होने के लिए, ऐसा कोई कारण नहीं है कि डब्ल्यूसीएफ अनुबंध को वस्तु के उपभोक्ताओं द्वारा उपयोग की जाने वाली एपीआई से मेल खाना पड़े, और वास्तव में, मैं आम तौर पर सुझाव दूंगा कि यदि आप इसे स्पष्ट करते हैं तो आप लंबे समय तक बेहतर हो जाएंगे ऊपर सामने – kyoryu

2

अमेज़ॅन उत्पाद विज्ञापन API वेब सेवा एक ही समस्या का एक अच्छा उदाहरण है जिसका आप अनुभव कर रहे हैं।

वे विभिन्न परिस्थितियों के आधार पर कॉलर्स को अधिक या कम विवरण प्रदान करने के लिए विभिन्न डीटीओ का उपयोग करते हैं। उदाहरण के लिए small response group, large response group और बीच में medium response group है।

अलग-अलग डीटीओ होने के नाते एक अच्छी तकनीक है यदि आप कहते हैं कि आप एक चिपचिपा इंटरफ़ेस नहीं चाहते हैं।

+0

बस सोच रहा है, आप विरासत पदानुक्रम में छोटे, मध्यम, बड़े प्रतिक्रिया समूह को कैसे संरेखित करेंगे? क्या ओआरएम हमेशा एक बड़े डीटीओ को बनाए रखना चाहिए और फिर छोटे डीटीओ और मध्यम डीटीओ केवल रैपर के रूप में होना चाहिए? – Jonn

+0

@ रिचर्डोड क्या आप कृपया http://stackoverflow.com/questions/9483286/understanding-data-outside-of-service-soa का उत्तर दे सकते हैं? – Lijo

1

मैं आम तौर पर अपनी जटिल वेब सेवाओं (यानी वेब सेवाएं जो संस्थाएं भेजता/प्राप्त करता हूं) में आलसी लोडिंग में निर्माण करता हूं। अगर किसी व्यक्ति के पास पिता की संपत्ति होती है (एक व्यक्ति भी), तो मैं नेस्टेड ऑब्जेक्ट की बजाय पिता के लिए सिर्फ एक पहचानकर्ता भेजता हूं, फिर मैं सुनिश्चित करता हूं कि मेरी वेब सेवा में एक ऑपरेशन है जो पहचानकर्ता को स्वीकार कर सके और संबंधित व्यक्ति इकाई के साथ जवाब दे सके । यदि ग्राहक पिता संपत्ति का उपयोग करना चाहता है तो क्लाइंट वेब सेवा को वापस कॉल कर सकता है।

मैंने इस पर भी विस्तार किया है ताकि बैचिंग हो सके। यदि कोई ऑपरेशन 5 व्यक्तियों को वापस भेजता है, तो यदि उन व्यक्तियों में से किसी एक पर पिता संपत्ति का उपयोग किया जाता है, तो उनके सभी 5 पिता के लिए उनके पहचानकर्ताओं के साथ अनुरोध किया जाता है। यह वेब सेवा की चतुरता को कम करने में मदद करता है।

+0

इस रणनीति का उपयोग करते हुए नोट इकाई पहचान की गंभीर जागरूकता की आवश्यकता है।हो सकता है कि आप एक ही इकाई के कई उदाहरणों को तैरना न चाहें; इसलिए आप अब तक प्राप्त संस्थाओं के क्लाइंट पर कैश बनाना चाहते हैं और उन लोगों का उपयोग कर सकते हैं जिन्हें आप की दूसरी प्रतिलिपि के लिए वापस जाने पर दिया गया है। –

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