2011-12-14 12 views
5

मान लीजिए कि मैं System.Data.SqlClient.SqlTransaction से उत्तराधिकारी बनाना चाहता हूं जो मुहरबंद है। मान लीजिए कि मैं सिर्फ SqlTransaction के आसपास एक रैपर डालना चाहता हूं और SqlTransaction के बजाय हमेशा MyTransaction का उपयोग करना चाहता हूं। क्या कोई तरीका है कि मैं संभावित रूप से MyTransaction से SqlTransaction पर लागू/प्रभावशाली ऑपरेटर का उपयोग कर सकता हूं?क्या सी #/वीबी.नेट में विरासत में भाग लेने का कोई तरीका है?

+5

'मान लीजिए मैं System.Data.SqlClient.SqlTransaction' => से प्राप्त करना तुम क्यों इस तरह कुछ करने के लिए चाहते हो जाएगा चाहते हैं? –

+4

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

+1

प्रतिबिंब का उपयोग कर कक्षा को अनदेखा करना संभव नहीं है? –

उत्तर

3

आप वास्तव में अंतर्निहित रूपांतरण चाहते हैं (हालांकि मैं इसे के रूप में यह एक भयानक विचार है और एक भयानक डिजाइन है, IMO की सिफारिश नहीं होगा,), तो आप कुछ इस तरह कर सकते हैं:

class MyTransaction 
    { 
     private readonly SqlTransaction _transaction; 

     public MyTransaction(SqlConnection conn) 
     { 
      _transaction = conn.BeginTransaction(); 
     } 

     public SqlTransaction Transaction 
     { 
      get 
      { 
       return _transaction; 
      } 
     } 

     public static implicit operator SqlTransaction(MyTransaction t) 
     { 
      return t.Transaction; 
     } 
    } 
+0

दुर्भाग्य से यह वीबीएनईटी में है और उनका चौड़ा ऑपरेटर काम नहीं कर रहा है क्योंकि सी # के "निहित" को मैंने अभी पाया है, लेकिन इस मार्ग के बारे में भी सोच रहा था ... हालांकि आपने कहा था कि मुझे यह पसंद नहीं है ... – Denis

+0

@ डेनिस आप कक्षा # में कक्षा को कोड करने का प्रयास कर सकते हैं और फिर अपने वीबी ऐप –

+1

@ डीनिस कोड में सी # में डीएलएल का उपयोग कर सकते हैं, वीबी में डिस्सेबल करने के लिए रिफेलक्टर का उपयोग करें और आप वाक्यविन्यास देखें। – TomTom

6

आप एक कक्षा बना सकते हैं जिसमें आंतरिक लेनदेन चर हो और फिर विधियों और गुणों का पर्दाफाश करें। एक तरह से इस तरह:

public class MyTransaction 
{ 
    System.Data.SqlTransaction myTx = someConnection.CreateTransaction(); 

    public void CommitTransaction() : { 
     myTx.CommitTransaction() 
    } 
} 

आप भी इसे DbTransaction से विरासत और उसके बाद सार और आभासी प्रक्रियाओं को फिर से लिखने भीतरी myTx चर का उपयोग करने के लिए कर सकता है, लेकिन यह कोई स्पष्ट असली कारण के लिए एक छोटे से जटिल हो रही शुरू होता है ...

+1

बिल्कुल! : -Þ लेकिन अगर आदमी लेनदेन लपेटना चाहता है, तो एक कारण हो सकता है! –

+0

सिर्फ इसलिए कि वह ऐसा करना चाहता है, और यहां तक ​​कि यदि संभव हो, तो इसका मतलब यह नहीं है कि उसे चाहिए। –

+0

@ रामहाउंड मैं सहमत हूं, लेकिन फिर भी यह अन्य लोगों के लिए सीखने का एक अच्छा तरीका है- ऐसे मामले जहां इस तरह का समाधान उपयुक्त है –

3

यदि आप कक्षा में अतिरिक्त विधियों को जोड़ने में रुचि रखते हैं तो आप विस्तार विधियों का उपयोग कर सकते हैं। यह आपको किसी भी आंतरिक स्थिति तक पहुंच नहीं देगा, या आपको व्यवहार को ओवरराइड करने की अनुमति नहीं देगा, लेकिन यह आपको सीमित कार्यक्षमता जोड़ने देगा। मुझे एक मुहरबंद वर्ग से उत्तराधिकारी के किसी भी तरीके से अवगत नहीं है।

आप एक वास्तविक रैपर ऑब्जेक्ट बना सकते हैं जैसा कि अन्य ने उल्लेख किया है, लेकिन आप मूल वस्तु के स्थान पर इसे polymorphically उपयोग करने में सक्षम नहीं होंगे।

+0

यह .NET 2.0 में है इसलिए कोई एक्सटेंशन विधियां नहीं हैं ... लेकिन मुझे ट्रैक रखने की भी आवश्यकता है सृजन के बाद से सामान ताकि एक्सटेंशन विधियां वैसे भी काम न करें। – Denis

+0

यह नहीं है कि यह .NET 2 चीज के कारण मायने रखता है, लेकिन एक्सटेंशन विधियां विस्तार विधि (ऑब्जेक्ट को घुमाने वाले ऑब्जेक्ट के पहले पैरामीटर) से कुंजीपटल किए गए शब्दकोश का उपयोग करके स्वतंत्र ऑब्जेक्ट डेटा को ट्रैक कर सकती हैं। यह डेटा का "विभाजन" सेट ऑफ़र कर सकता है जो आंतरिक स्थिति जैसा दिखता है लेकिन ऑब्जेक्ट के बाहर बाहरी संग्रहीत होता है। आंतरिक सदस्यों को प्रतिबिंब के माध्यम से पहुंचा जा सकता है, ताकि आप कुछ दिलचस्प चीजें कर सकें कि कैसे "बदसूरत" आप कोड को प्राप्त करने के इच्छुक हैं। –

+0

मुझे आशा है कि आपको कोई फर्क नहीं पड़ता है, लेकिन मैंने आपके प्रश्न में एक .net2.0 टैग जोड़ा है, इसलिए अन्य जानते हैं कि फ्रेमवर्क संस्करण सीमित है। –

0

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

+0

मैंने सोचा कि यह भी काम करेगा लेकिन फिर आपके पास SqlClient की तरह कुछ है।SQLCommand.Transaction जो SqlTransaction चाहता है, आईडीबीट्रांसैक्शन नहीं जो वास्तव में sux है, इसलिए मुझे नकली करने के लिए कुछ रास्ता चाहिए जिसने इस खोज को शुरू किया ... – Denis

1

नहीं, आप अपनी कस्टम कक्षा को एसक्लट्रांसक्शन से विरासत में प्राप्त नहीं कर सकते हैं या यह फिक्र नहीं कर सकते हैं।

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

+0

मैंने सोचा कि यह भी काम करेगा लेकिन फिर आपके पास SqlClient.SQLCommand.Transaction की तरह कुछ है जो SqlTransaction – Denis

+0

हाँ चाहता है , आप लपेटे हुए ऑब्जेक्ट्स के पूरे रैटनेस्ट में आते हैं ... आप सिस्टम से सभी कस्टम रैपर का उपयोग कर सकते हैं। डाटा नेमस्पेस एसक्यूएल संस्करणों को लपेटना .... यह सब इस बात पर निर्भर करता है कि आपकी आवश्यकताएं क्या हैं और आप इन वस्तुओं के साथ गड़बड़ क्यों कर रहे हैं पहले स्थान पर। लक्ष्य को पूरा करने के लिए अन्य (बेहतर) तरीके हैं। –

1

आप करना एक और विकल्प है, आप SqlTransaction में अपने चयन का एक इंटरफ़ेस जोड़ने के लिए Reflection.Emit() का उपयोग कर सकते हैं, और उसके बाद उसी इंटरफ़ेस का उपयोग अपने नए MyTransaction क्लास में कर सकते हैं और फिर आप क्लास के बजाय इंटरफ़ेस पर कॉल कर सकते हैं।

ध्यान रखें कि यह केवल आपके द्वारा बनाए गए पुस्तकालयों के भीतर ही काम करेगा, या प्रतिबिंब का उपयोग करके लोड किए गए प्रकारों को विशेष रूप से संशोधित करेगा।

+1

इसके अलावा, यह एक विशेष रूप से गंदे समाधान है ... –

+0

मैंने कभी प्रतिबिंब की कोशिश नहीं की है। प्रवेश()। मैं चारों ओर देखने जा रहा हूं लेकिन क्या आपके पास कोई अच्छा उदाहरण/ट्यूटोरियल है कि यह कैसे काम करेगा? – Denis

1

आप एक्सटेंशन विधियां बना सकते हैं।

public static class SqlTransactionExtensions 
{ 
    public static void DoSomething(this SqlTransaction transaction, int myParameter) 
    { 
     // do something here 
    } 
} 

कक्षा स्थिर होना चाहिए। मुट्ठी पैरामीटर के सामने जादू शब्द this रखें जो आपके द्वारा विस्तारित कक्षा के प्रकार का होना चाहिए। आप इंटरफेस भी बढ़ा सकते हैं। यदि आप इस विस्तार विधि का उपयोग करना चाहते हैं, तो आपके पास इस एक्सटेंशन क्लास के नामस्थान के साथ using namspace होना चाहिए, यदि यह उसी नामस्थान में परिभाषित नहीं है जिसमें आप काम कर रहे हैं।(टिप्पणी के आधार पर

SqlTransaction t = new SqlTransaction(); 
t.DoSomething(5); 
+0

यह एक अच्छा विचार है कि यहां किसी ने भी प्रस्तावित किया है लेकिन इसमें 2 समस्याएं हैं: (1) मैं .NET 2.0 का उपयोग कर रहा हूं और (2) यदि मैं .NET 2.0 का उपयोग नहीं कर रहा था, तो मैं ऑब्जेक्ट्स बनाने के लिए एक्सटेंशन विधियों का उपयोग कैसे करूं एसक्लट्रांसक्शन का निर्माण? (मान लें कि मैं यह ट्रैक करना चाहता हूं कि इस एसक्यूएल ट्रांज़ेक्शन या जिस समय इसे शुरू किया गया था) – Denis

+0

मैं लेनदेन के लिए एक स्थिर सहायक वर्ग बनाउंगा। एक्सटेंशन वर्ग की तरह, लेकिन 'इस' कीवर्ड के बिना। 'T.DoSomething (5);' के साथ विधियों को कॉल करने के बजाय, आपको उन्हें 'TransactionsHelper.DoSomething (t, 5);' के साथ कॉल करना होगा। विस्तार विधियां वास्तव में केवल वाक्य रचनात्मक चीनी हैं और वे ऐसा कुछ भी नहीं कर सकते जो सामान्य तरीकों से नहीं किया जा सके। –

2

ठीक है, तो विरासत को खारिज और काम आप वास्तव में हल करना चाहते पर ध्यान केंद्रित:

फिर आप विस्तार पद्धति के रूप में अगर यह SqlTransaction का एक नियमित विधि थी कॉल कर सकते हैं धागे)।

मुझे पिछली बार एक सहायक पुस्तकालय के माध्यम से सभी कॉल चलाने और वहां तर्क लागू करने में सफलता मिली है। अतीत में, मैंने एसक्लहेल्पर का उपयोग किया है, जो माइक्रोसॉफ्ट Data Application Block में प्रकाशित है। यह एक स्रोत मॉड्यूल है, जिसे आप अपनी आवश्यकताओं के अनुरूप कर सकते हैं। आप जो भी लॉगिंग या अन्य तर्क की आवश्यकता है उसे जोड़ सकते हैं।

यह कोड को बहुत पठनीय बनाता है।

SqlHelper.ExecuteScalar() प्रश्नों के लिए एकल मूल्यों लौटने

आदेशों जो कोई रिटर्न (जैसे INSERT के) के लिए SqlHelper.ExecuteNonQuery()

डेटा के सेट लौटने प्रश्नों के लिए SqlHelper.ExecuteDataset(),: आप की तरह कर सकते हैं।

आदि

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