मेरे पास एक DbQuery है जिसे मैं उपयोगकर्ता द्वारा प्रदान किए गए विभिन्न (वैकल्पिक) पैरामीटर के आधार पर फ़िल्टर करने का प्रयास कर रहा हूं। मैं इसके लिए LINQ के साथ क्वेरी लिखने की कोशिश कर रहा हूं लेकिन एक रोड़ा मारा है, इसलिए यह एक दो पार्टर है।

पोस्टग्रेज: मैं पोस्टग्रेज का उपयोग कर रहा हूं इसलिए मेरे पास एक सरणी कॉलम है, और मैं मूल रूप से useCaseArray && entity.useCases का उपयोग करने में सक्षम होना चाहता हूं। हालाँकि, EF प्रदाता वर्तमान में इसका समर्थन नहीं करता है।

मैं कच्चे एसक्यूएल में पूरी चीज लिखने के लिए नीचे नहीं जाना चाहता अगर मैं इससे बच सकता हूं तो मैंने सोचा कि मैं बहुत बदसूरत कर सकता हूं जहां इस तरह:

WHERE (useCases.Contains(x) || useCases.Contains(y) ...)

हालांकि मुझे नहीं पता कि LINQ के साथ इसे कैसे रचना करना है। मुझे पता है कि आप ओआरएस इनलाइन कर सकते हैं, जैसे

query.Where(item => item.cases.Contains(x) || item.cases.Contains(y))

हालांकि मैं इसे इस तरह नहीं लिख सकता क्योंकि मुझे अपने एक्स और वाई वाले सरणी पर फ़ोरैच/लूप की आवश्यकता है। क्या कोई जानता है मैं ऐसा कैसे कर सकता हूँ?

foreach(var usecase in request.UseCases) 
{
  query = query.Where(item => item.UseCases.Contains(usecase));
}

यह केवल ANDs की एक लंबी श्रृंखला उत्पन्न करेगा जब मैं जो चाहता हूं वह यह है कि संपूर्ण उपसमुच्चय एक OR होना चाहिए।

मुझे आशा है कि मैं इसे उचित रूप से समझाने में कामयाब रहा हूँ! वैकल्पिक रूप से मैं कच्चे एसक्यूएल में एक WHERE क्लॉज घटक को इंजेक्ट करने में सक्षम होना पसंद करूंगा, लेकिन मुझे लगता है कि इससे ईएफ कोर विस्फोट हो जाएगा और ऐसा लगता है कि FromSQL करना समर्थन नहीं करता है जहां बस चुनें।

अद्यतन करें:

टिप्पणी के आधार पर मैंने यह कोशिश की: https://petemontgomery.wordpress। com/2011/02/10/a-universal-predicatebuilder/ जो काफी हद तक काल्पनिक रूप से काम करता है:

var useCaseQuery = request.UseCases
  .Select(useCase => PredicateBuilder.Create<MyEntity>(entity => entity.UseCases.Contains(useCase)))
  .Aggregate(PredicateBuilder.Or);

query = query.Where(useCaseQuery);

यह एक तरह से बहुत अच्छा है, लेकिन EF Core अभी भी इसे पसंद नहीं करता है:

The LINQ expression 'where ({[assumption].UseCases => Contains(__useCase_3)} OrElse {[assumption].UseCases => Contains(__useCase_4)})' could not be translated and will be evaluated locally.

मुझे लगता है कि यह मेरे लिए ठीक रहेगा, लेकिन मूल समस्या अभी भी बनी हुई है, मैं इसे डीबी पर चलाना चाहता हूं।

2
Vassi 26 फरवरी 2019, 20:01

1 उत्तर

सबसे बढ़िया उत्तर

तो कुछ उपयोगी टिप्पणियों के बाद मैंने FromSql की कोशिश की

if (request.UseCases != null && request.UseCases.Count > 0)
{
  // I know UseCases is a List<int> hence why I'm just joining without escaping.
  query = query.FromSql("SELECT * FROM my_table WHERE ARRAY[" + String.Join(',', request.UseCases) + "] && use_cases");
}

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

if (request.Groups != null && request.Groups.Count > 0)
{
  query = query.Where(data => request.Groups.Contains(data.GroupId));
}

if (!String.IsNullOrWhiteSpace(request.Title))
{
  query = query.Where(data => EF.Functions.ILike(data.Name, $"%{request.Title}%"));
}

उत्पादित एसक्यूएल यह है:

SELECT my_table.classes, my_table."group", my_table.group_id, my_table.id, my_table.name, my_table.use_cases
FROM (
    SELECT * FROM my_table WHERE ARRAY[7,4] && use_cases
) AS assumption
WHERE my_table.group_id IN (7) AND (my_table.name ILIKE @__Format_3 ESCAPE '' = TRUE)
ORDER BY my_table.name DESC

जब तक पोस्टग्रेज ईएफ कोर ड्राइवर को अपडेट नहीं किया जाता है तब तक यह सबसे अच्छा हो सकता है जो मैं कर सकता हूं।

1
Vassi 26 फरवरी 2019, 23:30