2012-04-09 7 views
7

मेरे पास दो समान विधियां हैं जो मूल रूप से एक ही चीज़ को अलग-अलग वस्तुओं के साथ करती हैं। यदि संभव हो तो सामान्य से एक सामान्य विधि बनाने का सबसे अच्छा तरीका क्या है?दो समान अभी तक विभिन्न विधियों में से एक सामान्य विधि कैसे बनाएं?

दो वस्तुओं:

public class StoreObject { 
    int Key; 
    string Address; 
    string Country; 
    int Latitude; 
    int Longitude; 
} 

public class ProjectObject { 
    int ProjectKey; 
    string Address; 
    string Description; 
} 

दो तरीकों कि मैं संभवतः एक सामान्य बनाना चाहते हैं:

public StoreObject GetStoreByKey(int key) 
{ 
    using (DBEntities dbe = new DBEntities()) 
    { 
    StoreObject so = new StoreObject(); 
    var storeObject = (from s in dbe.StoreTables 
         where s.Key == key 
         select s).First(); 

    so.Key = storeObject.key; 
    so.Address = storeObject.address; 
    so.Country = storeObject.country; 
    so.Latitude = storeObject.latitude; 
    so.Longitude = storeObject.longitude; 

    return so; 
    } 
} 

public ProjectObject GetProjectByKey(int projectKey) 
{ 
    using (DBEntities dbe = new DBEntities()) 
    { 
    ProjectObject po = new ProjectObject(); 
    var projectObject = (from p in dbe.ProjectTables 
         where p.ProjectKey == projectKey 
         select p).First(); 

    po.Key = projectObject.p_key; 
    po.Address = projectObject.p_address; 
    po.Description = projectObject.p_description; 

    return po; 
    } 
} 

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

+1

इन तरीकों में एक समान नहीं है:

यदि आप थे सब समानता को अलग करने के लिए, यह कुछ ऐसा होगा। लगभग हर पंक्ति अलग है। आप अभिव्यक्ति में कहां से गुजर सकते हैं, लेकिन इससे केवल चीजें अधिक जटिल हो जाएंगी। उन तरीकों में से प्रत्येक तरीका जानता है कि वे जिस वस्तु से निपटते हैं उसका इलाज कैसे करें। मुझे लगता है कि यह उतना ही सारणित है जितना इसे प्राप्त करने जा रहा है। –

+0

वैसे मुझे तर्क देना होगा कि समानताएं हैं, और जब मैं मानता हूं कि यह पहले से ही सार है, तो मुझे लगा कि मैं कुछ अन्य लोगों को इसे और भी बनाने का विचार कर सकता हूं। – kei

उत्तर

3

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

public T GetEntityByKey<T>(int key) 
{ 
    using (DBEntities dbe = new DBEntities()) 
    { 
    return = dbe.StoreTables.Set<T>.Find(new object[] {key}); 
    } 
} 

और इसका इस्तेमाल करने के

StoreObject so = GetEntityByKey<StoreObject>(123); 
if(so != null) 
{ 
    int lat = so.Latitude; 
} 
+0

मैं हर किसी के इनपुट की सराहना करता हूं, लेकिन मुझे इसके लिए स्टीव के जवाब के साथ जाना होगा। (मुझे कुछ सामान बदलने की आवश्यकता होगी हालांकि मुझे केवल स्टोरटेबल्स से सामान नहीं मिल रहा है) – kei

2

आप वास्तव में लौटाए गए प्रकार को बाहर कर सकते हैं, और using कारक कर सकते हैं, लेकिन बाकी के लिए आपको अनुरोध किए गए प्रकार पर स्विच की आवश्यकता होगी या फ़ील्ड में पास करने के प्रतिबिंब और पैरामीटर के रूप में पुनर्प्राप्त करने के लिए प्रतिबिंब उपयोग।

पूर्व खराब अभ्यास होगा और समीकरण के लिए थोड़ा सा लाता है, और बाद वाला महंगा है और गन्दा हो सकता है।

यह जेनेरिक के लिए वास्तव में एक अच्छा उम्मीदवार नहीं है, जब तक कि आपके पास ऐसी कई तरह की समान विधियां नहीं हैं, इस मामले में मैं प्रतिबिंब दृष्टिकोण के लिए जाऊंगा।

एचटीएच,

बाब।

+0

मैंने प्रतिबिंब माना है, लेकिन मुझे लगा कि मैं यह देखने की कोशिश करता हूं कि यह सामान्य के रूप में ऐसा करना संभव है या नहीं। – kei

2

यह बहुत ही असंभव है कि यह आपकी पूरी 'काम की इकाई' है और इस प्रकार इन तरीकों में से प्रत्येक में ताजा DBEntities() संदर्भ का उपयोग शायद आपकी समस्या का मूल है।

एक Repository वर्ग है कि एक ही वेब अनुरोध के लिए DBEntities वर्ग का एक उदाहरण (या जो भी अन्य अनुरोध की इकाई आप अपने आवेदन में किया है) और शामिल बनाना उस में इन विधियों है जो डुप्लिकेट को नष्ट करने के लिए एक बेहतर दृष्टिकोण होगा कोड यहाँ using() का दायरा तब इन तरीकों से बाहर है और उम्मीद है कि आपके वेब अनुरोध या समय की अन्य इकाई से जुड़ा हुआ है।

एक नई कक्षा बनाने के बजाय एक विकल्प के रूप में आप DBEntities आंशिक कक्षा का विस्तार भी कर सकते हैं ताकि इन तरीकों को शामिल किया जा सके (माना जाता है कि यह जेनरेट कोड है)।

+0

अच्छा विचार है, लेकिन मैं अभी भी इसे सामान्य में बदलने की कोशिश करना चाहता हूं। – kei

2

आप अनिवार्य रूप से प्रत्येक विधि में दो अलग-अलग कार्य है:

  1. क्वेरी एक इकाई
  2. मानचित्र कि एक और प्रकार
को इकाई

था ई प्रथम भाग स्टीव मैलोरी द्वारा संबोधित किया गया है।

दूसरे भाग के लिए, आप एक उदाहरण से दूसरे में कॉपी करने वाले मानों को संभालने के लिए मैपर फ्रेमवर्क का उपयोग कर सकते हैं। चूंकि प्रत्येक प्रकार के नाम मेल नहीं खाते हैं, इसलिए आपको यह बताना होगा कि नामों को कैसे मैप करना है (आपके उदाहरण में, "p_" जोड़ना और इसे लोअरकेस बनाना)। एक संभावना Emit Mapper होगी।

public TResult GetById<TResult, TEntity>(int id) 
{ 
    using (DBEntities dbe = new DBEntities())  
    {   
     T result = dbe.StoreTables.Set<T>.Find(new object[] {key}); 
     var mapper = ObjectMapperManager.DefaultInstance 
      .GetMapper<TEntity, TResult>(
       new DefaultMapConfig().MatchMembers((m1, m2) => "p_" + m1.ToLower() == m2)); 

     return mapper.Map(result);  
    } 
} 
+0

हमम .. मैं इसे मानता हूं, लेकिन यह तीन क्षेत्रों को मैन्युअल रूप से मैप करने के लिए आसान हो सकता है। – kei

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