सशर्त लिंक प्रश्नोत्तरी

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

0
ro fr bn

11 उत्तर

अगर आप केवल तभी फ़िल्टर करना चाहते हैं यदि कुछ मानदंड पास हो जाएं, तो ऐसा कुछ करें

var logs = from log in context.Logs
           select log;

if (filterBySeverity)
    logs = logs.Where(p => p.Severity == severity);

if (filterByUser)
    logs = logs.Where(p => p.User == user);

ऐसा करने से इस तरह से आपके अभिव्यक्ति के पेड़ को वही होना चाहिए जो आप चाहते हैं। इस तरह बनाया गया एसक्यूएल वही होगा जो आपको चाहिए और कुछ भी कम नहीं।

0
जोड़ा
हाँ ... यह करना थोड़ा मुश्किल है। मैंने जो सबसे अच्छा देखा है वह विनिर्देश पैटर्न के माध्यम से है और विनिर्देश में भविष्यवाणी खींच रहा है और फिर विनिर्देशन को बुला रहा है। या (कुछ अन्य स्पेसिफिकेशन)। असल में आपको अपना खुद का अभिव्यक्ति पेड़ थोड़ा सा लिखना होगा। उदाहरण कोड और स्पष्टीकरण यहां: codeinsanity.com/archive/2008/08/13/…
जोड़ा लेखक Darren Kopp, स्रोत
यह उन्हें स्मृति में फ़िल्टर नहीं कर रहा है। यह एक प्रश्न बना रहा है और डेटाबेस में सभी शर्तों को भेज रहा है (कम से कम अधिकांश linq-to-x प्रदाताओं के लिए)
जोड़ा लेखक Darren Kopp, स्रोत
नमस्ते क्या आपके पास एंड्रॉइड के बजाय कहां क्लॉज बनाने के लिए कोई सुझाव है ..?
जोड़ा लेखक Jon H, स्रोत
मेरे पास एक बेवकूफ सवाल है, यदि ये लॉग डेटाबेस से अधिग्रहित किए जा रहे हैं, तो क्या हम सभी लॉग प्राप्त कर रहे हैं और फिर उन्हें स्मृति में फ़िल्टर कर रहे हैं? यदि ऐसा है तो मैं डेटाबेस को शर्तों को कैसे पास कर सकता हूं
जोड़ा लेखक Ali Umair, स्रोत
यह त्रुटि LINQ से इकाइयों को प्राप्त करने की विधि 'System.String get_Item (System.String)' विधि को पहचान नहीं पाती है, और इस विधि को स्टोर अभिव्यक्ति में अनुवादित नहीं किया जा सकता है।
जोड़ा लेखक Ali Umair, स्रोत
@AliUmair मुझे इसी तरह की त्रुटियां थीं। LINQ सरणी अनुक्रमण को समझ में नहीं आता है। अपने सरणी तत्व मान को स्थानीय चर में खींचें और क्वेरी में अपने चर का उपयोग करें। उदाहरण: इसके बजाय: var query = x में संदर्भ से। Logs जहां x.User == myArray [0] लॉग का चयन करें; उपयोग करें: var u = myArray [0]; var क्वेरी = x से संदर्भ में। logs जहां x.User == आप लॉग का चयन करें;
जोड़ा लेखक Suncat2000, स्रोत

मैंने डैरेन के समान उत्तर का उपयोग करना समाप्त कर दिया, लेकिन एक IQueryable इंटरफ़ेस के साथ:

IQueryable matches = m_Locator.Logs;

// Users filter
if (usersFilter)
    matches = matches.Where(l => l.UserName == comboBoxUsers.Text);

//Severity filter
 if (severityFilter)
     matches = matches.Where(l => l.Severity == comboBoxSeverity.Text);

 Logs = (from log in matches
         orderby log.EventTime descending
         select log).ToList();

डेटाबेस को मारने से पहले यह क्वेरी बनाता है। आदेश तब तक नहीं चलेगा जब तक अंत में टॉलिस्ट ()।

0
जोड़ा

खैर, मैंने सोचा था कि आप फिल्टर शर्तों को भविष्यवाणियों की एक सामान्य सूची में डाल सकते हैं:

    var list = new List { "me", "you", "meyou", "mow" };

    var predicates = new List>();

    predicates.Add(i => i.Contains("me"));
    predicates.Add(i => i.EndsWith("w"));

    var results = new List();

    foreach (var p in predicates)
        results.AddRange(from i in list where p.Invoke(i) select i);               

इसके परिणामस्वरूप "मुझे", "meyou", और "mow" वाली एक सूची होती है।

आप भविष्यवाणी कर सकते हैं कि भविष्यवाणियों के साथ एक पूरी तरह से अलग कार्य में भविष्यवाणी करें जो सभी भविष्यवाणी करता है।

0
जोड़ा

आप बाहरी विधि का उपयोग कर सकते हैं:

var results =
    from rec in GetSomeRecs()
    where ConditionalCheck(rec)
    select rec;

...

bool ConditionalCheck( typeofRec input ) {
    ...
}

यह काम करेगा, लेकिन अभिव्यक्ति पेड़ में तोड़ा नहीं जा सकता है, जिसका मतलब है कि लिंक से एसक्यूएल प्रत्येक रिकॉर्ड के खिलाफ चेक कोड चलाएगा।

वैकल्पिक रूप से:

var results =
    from rec in GetSomeRecs()
    where 
        (!filterBySeverity || rec.Severity == severity) &&
        (!filterByUser|| rec.User == user)
    select rec;

यह अभिव्यक्ति पेड़ों में काम कर सकता है, जिसका मतलब है कि लिंक से एसक्यूएल अनुकूलित किया जाएगा।

0
जोड़ा

एक और विकल्प PredicateBuilder जैसे कुछ का उपयोग करना होगा यहां पर चर्चा की। यह आपको निम्न जैसे कोड लिखने की अनुमति देता है:

var newKids  = Product.ContainsInDescription ("BlackBerry", "iPhone");

var classics = Product.ContainsInDescription ("Nokia", "Ericsson")
                  .And (Product.IsSelling());

var query = from p in Data.Products.Where (newKids.Or (classics))
            select p;

ध्यान दें कि मुझे केवल लिंक 2 एसक्यूएल के साथ काम करने के लिए मिला है। EntityFramework Expression.Invoke को लागू नहीं करता है, जो इस विधि के लिए काम करने के लिए आवश्यक है। मेरे पास इस समस्या के बारे में एक प्रश्न है यहां

0
जोड़ा
डाटा ट्रांसफर ऑब्जेक्ट्स और एंटिटी मॉडल के बीच मैप करने के लिए ऑटोमैपर जैसे टूल के साथ उनके रिपोजिटरी के शीर्ष पर बिजनेस लॉजिक लेयर का उपयोग करने वालों के लिए यह एक शानदार तरीका है। भविष्यवाणी निर्माता का उपयोग करने से आप अपने IQueryable को गतिशील रूप से संशोधित करने की अनुमति देंगे ताकि इसे फ़्लैटनिंग के लिए ऑटोमैपर पर भेजने से पहले सूची को स्मृति में लाया जा सके। ध्यान दें कि यह इकाई फ्रेमवर्क का भी समर्थन करता है।
जोड़ा लेखक chrisjsherm, स्रोत

When it comes to conditional linq, I am very fond of the filters and pipes pattern.
http://blog.wekeroad.com/mvc-storefront/mvcstore-part-3/

असल में आप प्रत्येक फ़िल्टर केस के लिए एक एक्सटेंशन विधि बनाते हैं जो IQueryable और पैरामीटर में होता है।

public static IQueryable HasID(this IQueryable query, long? id)
{
    return id.HasValue ? query.Where(o => i.ID.Equals(id.Value)) : query;
}
0
जोड़ा

यह सबसे सुंदर चीज नहीं है लेकिन आप लैम्ब्डा अभिव्यक्ति का उपयोग कर सकते हैं और वैकल्पिक रूप से अपनी शर्तों को पार कर सकते हैं। टीएसक्यूएल में पैरामीटर वैकल्पिक बनाने के लिए मैं निम्नलिखित में से बहुत कुछ करता हूं:

जहां फ़ील्ड = @ फ़ील्डवायर या @ फ़ील्डवायर नल

है

आप निम्न लैम्ब्डा (प्रमाणन जांचने का एक उदाहरण) के साथ एक ही शैली को डुप्लिकेट कर सकते हैं:

MyDataContext db = new MyDataContext();

void RunQuery(string param1, string param2, int? param3){

Func checkUser = user =>

((param1.Length > 0)? user.Param1 == param1 : 1 == 1) &&

((param2.Length > 0)? user.Param2 == param2 : 1 == 1) &&

((param3 != null)? user.Param3 == param3 : 1 == 1);

User foundUser = db.Users.SingleOrDefault(checkUser);

}

0
जोड़ा

I had a similar requirement recently and eventually found this in he MSDN. CSharp Samples for Visual Studio 2008

डाउनलोड के डायनामिकQuery नमूने में शामिल कक्षाएं आपको निम्न प्रारूप में रनटाइम पर गतिशील क्वेरी बनाने की अनुमति देती हैं:

var query =
db.Customers.
Where("City = @0 and Orders.Count >= @1", "London", 10).
OrderBy("CompanyName").
Select("new(CompanyName as Name, Phone)");

इसका उपयोग करके आप रनटाइम पर गतिशील रूप से एक क्वेरी स्ट्रिंग बना सकते हैं और इसे कहां() विधि में पास कर सकते हैं:

string dynamicQueryString = "City = \"London\" and Order.Count >= 10"; 
var q = from c in db.Customers.Where(queryString, null)
        orderby c.CompanyName
        select c;
0
जोड़ा

Just use C#'s && operator:

var items = dc.Users.Where(l => l.Date == DateTime.Today && l.Severity == "Critical")

संपादित करें: आह, अधिक सावधानी से पढ़ने की जरूरत है। आप जानना चाहते थे कि कैसे सशर्त रूप से अतिरिक्त खंड जोड़ें। उस मामले में, मुझे कोई जानकारी नहीं है। :) जो मैं संभवतः करता हूं, उसके आधार पर मैं केवल कई प्रश्नों को तैयार करता हूं, और सही निष्पादित करता हूं।

0
जोड़ा

यदि आपको किसी सूची/ऐरे पर आधार फ़िल्टर करने की आवश्यकता है तो निम्न का उपयोग करें:

    public List GetData(List Numbers, List Letters)
    {
        if (Numbers == null)
            Numbers = new List();

        if (Letters == null)
            Letters = new List();

        var q = from d in database.table
                where (Numbers.Count == 0 || Numbers.Contains(d.Number))
                where (Letters.Count == 0 || Letters.Contains(d.Letter))
                select new Data
                {
                    Number = d.Number,
                    Letter = d.Letter,
                };
        return q.ToList();

    }
0
जोड़ा
यह अब तक का सबसे अच्छा और सबसे सही उत्तर है। सशर्त || केवल पहले भाग की तुलना करता है और दूसरा भाग छोड़ देता है यदि पहला भाग सच है ... अच्छी तरह से किया गया!
जोड़ा लेखक Serj Sagan, स्रोत
इस निर्माण में जेनरेट की गई SQL क्वेरी में अभिव्यक्ति का 'या' भाग शामिल है। स्वीकार्य उत्तर अधिक कुशल बयान उत्पन्न करेगा। निश्चित रूप से डेटा प्रदाता के अनुकूलन के आधार पर। LINQ-to-SQL में बेहतर अनुकूलन हो सकता है, लेकिन LINQ-to-Entities नहीं है।
जोड़ा लेखक Suncat2000, स्रोत

यह कर रहा हूं:

bool lastNameSearch = true/false;//depending if they want to search by last name,

इसे जहां कथन में रखना है:

where (lastNameSearch && name.LastNameSearch == "smith")

इसका अर्थ यह है कि जब अंतिम क्वेरी बनाई जाती है, तो lastNameSearch false है, तो क्वेरी अंतिम नाम खोज के लिए पूरी तरह से किसी भी SQL को छोड़ देगी।

0
जोड़ा
डेटा प्रदाता पर निर्भर करता है। LINQ-to-Entities इसे अच्छी तरह अनुकूलित नहीं करता है।
जोड़ा लेखक Suncat2000, स्रोत