2012-01-28 11 views
5

मुझे पूरा यकीन है कि मुझे पता है कि उत्तर नहीं है, लेकिन आखिरी खाई के प्रयास के रूप में मैंने सोचा कि मैं यहां सवाल पूछूंगा।क्या IQueryable अभिव्यक्ति को मैन्युअल रूप से संशोधित करना संभव है

मैं पहली बार हमेशा की तरह फैशन

_context.Set<Foo>().Where(f => f.Bar == 999); 

जो निम्नलिखित अभिव्यक्ति (मैं सिर्फ यह तो यह गलत हो सकता है लिखा है) बनाता है में एक तालिका क्वेरी करने के लिए एफई कोड का उपयोग कर रहा

{SELECT 
[Extent1].[Test] AS [Test], 
[Extent1].[Test2] AS [Test2], 
FROM [dbo].[Foo] AS [Extent1] 
WHERE 19 = [Extent1].[Bar]} 

अब, तालिका नाम को बदलने के लिए मैन्युअल रूप से संशोधित करना संभव है, कहें, Foo10? (शायद नहीं)

यह विफल होने पर, क्या किसी को पता है कि मैं पहले कोड में टेबल नाम "देर से बांध" सकता हूं?

आप शायद सोच रहे हैं "गंदा हैक क्यों?" हमेशा की तरह, यह डेटाबेस के साथ एक विरासत मुद्दा है जिसमें कुछ डिज़ाइन समस्याएं हैं और इसे बदला नहीं जा सकता है।

अग्रिम धन्यवाद।

Ps। मुझे पता है कि मैं Database.SqlQuery का उपयोग कर सकता हूं लेकिन इसके बजाय नहीं।

+0

आपके मॉडल में टेबल 'Foo10' क्यों नहीं है? – BrokenGlass

+0

क्योंकि तकनीकी रूप से यह वही मॉडल कई तालिकाओं में फैल गया है। आपके डेटा में मौजूद तालिका पैरामीटर –

+0

@mjmcloug के आधार पर भिन्न होती है, यह कैसे निर्भर करती है? – Krizz

उत्तर

0

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

सुगंधित और हैकी लेकिन संभव है?

+0

जहां तक ​​मुझे पता है, केवल तभी संभव है जब आप एंटिटी फ्रेमवर्क के उपयोग को फेंकने के इच्छुक हैं - जिसका अर्थ है कि आप एसक्यूएल को हाथ से भी लिख सकते हैं। – Bevan

+0

मैंने ऐसा करने के बारे में सोचा है। इसकी संभावना है कि यह डेटा केवल पढ़ने जा रहा है, इसलिए यह उपयुक्त हो सकता है। हालांकि थोड़ा सा डोडी सोचें: डी –

+0

@ बेवन इसकी कुल बर्बादी नहीं है। इसका मतलब यह होगा कि हम सामान्य फैशन में अभिव्यक्ति का निर्माण कर सकते हैं और प्रत्येक मिनट के लिए एक नई एसक्यूएल क्वेरी होने के बजाय आखिरी मिनट में इसे बदल सकते हैं, जहां हम –

1

आप मान लिया जाये कि मैं उन सभी मॉडल में जोड़ सकते हैं और एक आम इंटरफेस सभी वर्गों को लागू करेगा बनाने और उसके बाद पर्याप्त मॉडल का चयन करें और क्वेरी करने के लिए Dynamic Linq का प्रयोग करेंगे, टेबल की उचित संख्या है।

मुझे यकीन है कि अगर यह काम करता है नहीं कर रहा हूँ, यह जाँच की है नहीं और साथ "एफई कोड-पहले" काम नहीं किया है, लेकिन यह कुछ मैं कोशिश करेगा है:

की अपनी मेज (रों) मान लीजिए Foo फ़ील्ड हैं - Bar, Pub, X और X जो संबंधित तालिका पर निर्भर करता है?

interface IFoo 
{ 
    int Bar { get; set; } 
    string Pub { get; set; } 
    int X { get; set; } 
} 

फिर प्रत्येक तालिका मॉडल में अपने वर्ग होगा:

फिर, मैं इंटरफेस को परिभाषित करेगा

[Table("Foo1")] 
class Foo1 : IFoo 
{ 
    public int Bar { get; set; } 
    public string Pub { get; set; } 
    public int X { get; set; } 
} 

[Table("Foo2")] 
class Foo2 : IFoo 
{ 
    public int Bar { get; set; } 
    public string Pub { get; set; } 
    public int X { get; set; } 
} 

तो आप निम्नलिखित की तरह उन्हें फ़िल्टर कर सकते हैं:

IQueryable GetAdequateFoo(int X) 
{ 
    switch (X) // you could use reflection here to dynamically call the given Set<Foo#>() 
    { 
     case 1: 
     return _context.Set<Foo1>(); 
     case 2: 
     return _context.Set<Foo2>(); 
     default: 
     return null; 
    } 
} 

IFoo GetFooByBarAndX(int bar, int X) 
{ 
    IQueryable context = GetAdequateFoo(X); 
    return context.Where("it.Bar == @0", bar).Cast<IFoo>(); 
} 

यह सिर्फ परीक्षण नहीं किया गया है और सिर से लिखा गया है, अगर मैं गलत हूं और किसी भी पेट को इंगित करता हूं तो कृपया मत छोड़ो टाइल समस्याएं

+0

हा, मैं इस जवाब को वोट देने वाला नहीं हूं, यह वास्तव में ईएफ को फैक्ट्री विधि लागू करने के लिए एक सुंदर चालाक विचार है। मेरे पास एक विचार नहीं होगा हालांकि मुझे मैपिंग कक्षाएं भी मिली हैं, इसलिए इसे स्थापित करने के लिए बहुत सी कक्षाएं हैं। चालाक विचार हालांकि! –

2

आप अपने मॉडल पर TPT विरासत का उपयोग क्यों नहीं करते?

@ Krizz के उत्तर के समान, लेकिन आप गतिशील LINQ का उपयोग करने से बचें।

यदि किसी विशेष पैरामीटर Foo1 में 1 देखो के एक मूल्य है अगर इसकी foo2 में और इतने

तो पर 2 देखो, तो आप ऐसा कर सकते हैं:

अपनी टिप्पणी का उपयोग

+०१२३५१६४१०६१:
var query = ctx 
    .Foos 
    .OfMyType(value) 
    .Where(f => f.Bar == 999) // f.Bar is on the base/abstract entity. 
    .ToList(); 

कहाँ OfMyTypeIQueryable<T> पर एक कस्टम विस्तार विधि है

public static IQueryable<T> OfMyType<T>(this IQueryable<T> source, string value) 
{ 
    switch (value) 
    { 
     case "1": 
     return source.OfType<Foo1>(); 
     case "2": 
     return source.OfType<Foo2>(); 
     // etc, etc 
    } 
} 

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

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

क्या यह काम करेगा?

+0

फिर यह अच्छा लग रहा है। मुझे इसे जाने और आपको वापस लेना होगा। लेकिन फिर मेरा एकमात्र मुद्दा यह है कि इसका मतलब है कि कई कक्षाएं उत्पन्न करना जिन्हें मैं टालने की कोशिश कर रहा हूं। प्यार विरासत होना चाहिए! –

+1

+1 फ्रेमवर्क ऑफ़र का उपयोग करके मेरे दृष्टिकोण को सरल बनाने के लिए अच्छा है। – Krizz

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

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