2012-09-17 25 views
13

द्वारा इकाई मिल रहा है निम्नलिखित कोड (उदाहरण):इकाई की रूपरेखा - नाम

public dynamic GetData(string name) 
{ 
    using(var ctx = GetObjectContext()) 
    { 
     switch (name) 
     { 
     case "entity1": 
      return ctx.entity1.ToList(); 
     case "entity2": 
      return ctx.entity2.ToList(); 
     ...... 
     default: 
      return null; 
     } 
    } 
} 

मैं इस नमूने में स्विच बचना चाहते हैं। मैं नाम से आवश्यक इकाई वर्ग कैसे ढूंढ सकता हूं, ToList() विधि को कॉल कर सकता हूं और डेटा वापस कर सकता हूं? क्या मैं प्रतिबिंब का उपयोग कर ऐसा कर सकता हूं? क्या आप मेरी मदद कर सकते हैं?

उत्तर

22

आप इसे प्रतिबिंब का उपयोग करके कर सकते हैं, हालांकि आपको जेनिक्स का उपयोग करने की भी आवश्यकता होगी क्योंकि प्रत्येक इकाई प्रकार के लिए ToList() विधि द्वारा लौटाई गई सूची का प्रकार अलग है।

तुम इतनी तरह प्रतिबिंब के माध्यम से एक संपत्ति गेटर पहुँच सकते हैं:

var enumerable = typeof([ClassNameOfContext]).GetProperty(name).GetValue(ctx, null); 

[ClassNameOfContext] जबकि वर्ग कि ctx का एक उदाहरण है का नाम है। यह आपके कोड से स्पष्ट नहीं है, लेकिन आप जानते हैं कि यह :-)

समस्या यह है कि enumerable एक object हो जाएगा और IEnumerable<EntityType> जहां EntityType इकाई के प्रकार आप तक पहुँच रहे हैं है करने के लिए casted किया जाना है। दूसरे शब्दों में, यह आपके द्वारा पारित किए जा रहे नाम पर निर्भर करता है। यदि आप प्रकार निर्धारित करने के लिए जेनेरिक का उपयोग करते हैं, तो आप ऑब्जेक्ट को सही ढंग से डालने में सक्षम होंगे और dynamic भी वापस नहीं लौटना होगा।

public TEntity Get<TEntity>(string name) 
{ 
    ... 

और ऊपर से लाइन को बदलने:

var enumerable = (IEnumerable<TEntity>)(typeof([ClassNameOfContext]).GetProperty(name).GetValue(ctx, null)); 
return enumerable.ToList(); 
यहाँ

तुम जाओ!

अनुपूरक: आप स्ट्रिंग पैरामीटर से छुटकारा पाने के लिए भी, कल्पना कर सकते हैं - स्ट्रिंग्स में प्रकारों या गुणों के नाम होने से कहीं भी बचा जाना चाहिए क्योंकि यह सुरक्षित नहीं है। कंपाइलर इसे पहचान नहीं पाता है, और आईडीई फीचर्स जैसे रेफैक्टरिंग्स इसके लिए जिम्मेदार नहीं हैं। यहां समस्या यह है कि संपत्ति के नाम आमतौर पर इकाई प्रकार के नामों का बहुवचन रूप होते हैं। लेकिन आप उस संपत्ति को खोजने के लिए प्रतिबिंब का उपयोग कर सकते हैं जिसका प्रकार TEntity से मेल खाता है। मैं एक अभ्यास :-)

+0

प्रतिबिंब का उपयोग करके मैं इसे कैसे कर सकता हूं? ToList द्वारा लौटाया गया प्रकार कोई फर्क नहीं पड़ता, क्योंकि GetData रिटर्न प्रकार गतिशील है - इसलिए यह किसी भी प्रकार – user1209216

+0

@ user1209216 हो सकता है - मैंने अपना जवाब अपडेट किया। – chiccodoro

+0

@ user1209216 - आप मुझे लगता है कि एक समस्या के आसपास काम करने के लिए गतिशील का उपयोग कर रहे हैं। 'गतिशील' कीवर्ड का आकलन किया जाना चाहिए। इसमें इसका बहुत ही विशिष्ट उपयोगिक मामले हैं जहां इसका उपयोग करना उचित है, लेकिन आपके मामले में आप पूरी तरह से अपने रिटर्न प्रकार को टाइप करने में सक्षम हैं। यह जाने का पसंदीदा तरीका है। – chiccodoro

0

के रूप में इस छोड़ने के लिए आप इस

private IEnumerable<TEntity> GetList<TEntity>(string connectionString, Func<object, T> caster) 
{ 
    using (var ctx = new DbContext(connectionString)) 
    { 
     var setMethod = ctx.GetType().GetMethod("Set").MakeGenericMethod(typeof(T)); 

     var querable = ((DbSet<object>)setMethod 
     .Invoke(this, null)) 
     .AsNoTracking() 
     .AsQueryable(); 

     return querable 
      .Select(x => caster(x)) 
      .ToList(); 
    } 
} 

की तरह कोड का उपयोग कर सकते इस तरह कॉल करने के लिए:

var branchList = GetList<Branch>("connectionStringName", x => (Branch)x); 

आप .AsNoTracking() को हटाने और निकाल सकते हैं .ToList(), तो आपको शुद्ध IQueryable मिलेगा जिसे आप आगे पूछ सकते हैं।

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