Linq में SQL Like% कैसे करें?


385

मेरी SQL में एक प्रक्रिया है जिसे मैं Linq में बदलने की कोशिश कर रहा हूँ:

SELECT O.Id, O.Name as Organization
FROM Organizations O
JOIN OrganizationsHierarchy OH ON O.Id=OH.OrganizationsId
where OH.Hierarchy like '%/12/%'

मैं जिस लाइन से सबसे ज्यादा चिंतित हूं वह है:

where OH.Hierarchy like '%/12/%'

मेरे पास एक कॉलम है जो पदानुक्रम को स्टोर करता है जैसे / 1/3/12 / उदाहरण के लिए इसलिए मैं बस इसका उपयोग करने के लिए% / 12 /% का उपयोग करता हूं।

मेरा प्रश्न यह है कि प्रतिशत चिह्न का उपयोग करने के लिए लाइनक या .NET क्या है?


1
आपके सवाल में कम से कम 5वोट हैं जैसे ऑपरेटर टैग के लिए। क्या मैं आपसे अनुरोध कर सकता हूं कि आप एक पर्याय के रूप में sql- जैसा सुझाव दें ?
कर्मी

जवाबों:


550
.Where(oh => oh.Hierarchy.Contains("/12/"))

तुम भी उपयोग कर सकते हैं .StartsWith()या .EndsWith()


4
स्टार्टस्विथ () या एंडस्विथ () का उपयोग करके एक क्वेरी को आग लगाएगा? मेरा मतलब है, क्या कोड को क्वेरी में अनुवादित किया जाएगा या परिणाम डीबी से पुनर्प्राप्ति के बाद ऑब्जेक्ट में फ़िल्टर किया जाएगा?
नौसिखिया

5
प्रारंभ प्रारंभ () और एंडस्विथ () विधेय / फ़िल्टर का हिस्सा हैं। निर्वासन जारी है।
-लेर

2
कोशिश की गई कि NullReferenceException मिली: ऑब्जेक्ट संदर्भ किसी ऑब्जेक्ट की आवृत्ति पर सेट नहीं है। तो यह यह पसंद नहीं करता जब मेरे मामले में a.Address1.StartsWith (पता 1) और a.Address1 रिक्त है
MikeT

11
StartsWith("abc")में परिवर्तित हो जाता है LIKE 'abc%'और EndsWith("abc")इसे cnovertedLIKE '%abc'
Simon_Weaver

20
काम नहीं कर सका, यह पत्रों के साथ उपयोग के मामले में काम क्यों नहीं कर रहा था, तो मुझे अपनी मूर्खता का एहसास हुआ ... .ToLower().Contains()यदि आप मामले को अनदेखा करना चाहते हैं तो भूल न करें । आप चाहते हैं कि यह निश्चित रूप से इस बात पर निर्भर करता है कि आपके मामले को असंवेदनशील टकराव के साथ एक DB से LIKE करना है या नहीं।
एडम नाइट

251

इसे इस्तेमाल करो:

from c in dc.Organization
where SqlMethods.Like(c.Hierarchy, "%/12/%")
select *;

22
यह वास्तव में उपयोगी है यदि आप इस तरह के कमांड द्वारा प्रदान किए गए अधिक जटिल पैटर्न का उपयोग करना चाहते हैं। उदाहरण के लिए, यदि आप किसी भी दो संख्याओं (12 के बजाय) की जांच करना चाहते हैं, तो आप इस अभिव्यक्ति का उपयोग कर सकते हैं: SqlMethods.Like (c.Hierarchy, "% / [0-9] [0-9] /%") , यह देखें msdn.microsoft.com/en-us/library/aa933232(SQL.80).aspx
viggity

यह भी बहुत उपयोगी है यदि आप पावर उपयोगकर्ताओं को महंगे शुरुआती% स्वयं को प्री-पेंड करने की अनुमति देना चाहते हैं, जहां स्टार्टस्विथ या कॉन्टेंस का उपयोग करने से पावर उपयोगकर्ता को यह लचीलापन नहीं मिलता है
सिमोन_विवर

8
आप SqlMethods"डॉट नोटेशन" का उपयोग कैसे करते हैं ?
dan-gph

12
ध्यान दें कि आपको System.Data.Linq.SqlClientनामस्थान शामिल करने की आवश्यकता है ।
जोहना

1
मुझे System.Data.Linq.SqlClient नहीं मिला, हालांकि मैं System.Data.Linq जोड़ सकता हूं। क्या यह पदावनत है?
बुरक करकुस

41

मैं मान रहा हूं कि आप Linq-to-SQL * (नीचे नोट देखें) का उपयोग कर रहे हैं। यदि ऐसा है, तो SQL उत्पन्न करने वाले SQL का उपयोग करने के लिए string.Contains, string.StartsWith और string.EndsWith का उपयोग करें।

from o in dc.Organization
join oh in dc.OrganizationsHierarchy on o.Id equals oh.OrganizationsId
where oh.Hierarchy.Contains(@"/12/")
select new { o.Id, o.Name }

या

from o in dc.Organization
where o.OrganizationsHierarchy.Hierarchy.Contains(@"/12/")
select new { o.Id, o.Name }

नोट: * = यदि आप .net 3.5 में ADO.Net इकाई फ्रेमवर्क (EF / L2E) का उपयोग कर रहे हैं, तो ध्यान रखें कि यह Linq-to-SQL के समान अनुवाद नहीं करेगा। हालांकि L2S एक उचित अनुवाद करता है, L2E v1 (3.5) एक टी-एसक्यूएल अभिव्यक्ति में अनुवाद करेगा जो आपके द्वारा क्वेरी किए जा रहे टेबल पर एक पूर्ण टेबल स्कैन को बाध्य करेगा जब तक कि आपके क्लॉज या फिल्टर में शामिल होने में एक और बेहतर भेदभाव न हो।
अपडेट: यह EF / L2E v4 (.net 4.0) में तय किया गया है, इसलिए यह एक LIKE करता है जैसे L2S करता है।


@संकेत के साथ अपने तार से बचने की जरूरत नहीं है , लेकिन मुझे लगता है कि यह सिर्फ एक अच्छा सम्मेलन का पालन करने के लिए हो सकता है।
andleer

27

यदि आप VB.NET का उपयोग कर रहे हैं, तो उत्तर "*" होगा। यहां जानिए आपका ऐसा क्लॉज कहां दिखेगा ...

Where OH.Hierarchy Like '*/12/*'

नोट: "*" शून्य या अधिक वर्णों से मेल खाता है। यहाँ लाइक ऑपरेटर के लिए msdn लेख है


क्या VB लाइक ऑपरेटर L2S कॉल में अनुवाद करता है? (मुझे कोई पता नहीं है।)
-लेर

8
हाँ, VB लाइक ऑपरेटर LINQ क्वेरी एक्सप्रेशन में उपयोग किए जाने पर एसक्यूएल संस्करण में अनुवादित हो जाता है। साथ ही, VB लाइक ऑपरेटर क्वेरी अभिव्यक्तियों तक सीमित नहीं है।
रोबर्ट्ज़

1
मैंने देखा कि यह LINQ ऑपरेशन के बाहर मौजूद था। अच्छी चीज़। +1
-लेयर

9

अच्छी तरह से indexOf मेरे लिए भी काम करता है

var result = from c in SampleList
where c.LongName.IndexOf(SearchQuery) >= 0
select c;

1
यह स्वीकृत उत्तर होना चाहिए। IndexOf sql में CHARINDEX का अनुवाद करता है। यह संभवतः LIKE से तेज हो सकता है। लेकिन इसके अलावा, यह 'कुछ%%%%' जैसे खोज प्रश्नों का निर्माण करने की possiblity देता है। जहां Where कुछ ’को 'चीज’ से पहले स्थित होना चाहिए, जो कि कंटेन्स के साथ नहीं किया जा सकता है।
Ruard van Elburg

मुझे यह पसंद है जब मेरे उत्तर की आवश्यकता 8 वर्ष की है और स्वीकृत उत्तर के नीचे कई स्तरों को टक किया गया है। सीधे शब्दों में कहें, यह काम किया है जबकि .Contains (@ "/ 12 /") और इसी तरह के अन्य उत्तर नहीं थे। बहुत सराहना की!
IdusOrtus

4

ऐसे कोड का इस्तेमाल करें

try
{
    using (DatosDataContext dtc = new DatosDataContext())
    {
        var query = from pe in dtc.Personal_Hgo
                    where SqlMethods.Like(pe.nombre, "%" + txtNombre.Text + "%")
                    select new
                    {
                        pe.numero
                        ,
                        pe.nombre
                    };
        dgvDatos.DataSource = query.ToList();
    }
}
catch (Exception ex)
{
    string mensaje = ex.Message;
}

4

.NET कोर अब है EF.Functions.Like


क्या आप बता सकते हैं कि ओपी की समस्या को हल करने के लिए इसका उपयोग कैसे करें?
रॉबर्ट कोलंबिया

एल.पी. का जवाब देखें, यह सिर्फ SqlMethods का मुख्य संस्करण है। लाइक करें
kofifus

इस उत्तर में इस फ़ंक्शन का उपयोग करने का एक क्रियाशील उदाहरण होना चाहिए।
फॉक्सडिपल

3

यदि आप संख्यात्मक तार का मिलान नहीं कर रहे हैं, तो हमेशा सामान्य स्थिति के लिए अच्छा है:

.Where(oh => oh.Hierarchy.ToUpper().Contains(mySearchString.ToUpper()))

2

मैं हमेशा ऐसा करता हूं:

from h in OH
where h.Hierarchy.Contains("/12/")
select h

मुझे पता है कि मैं इस तरह के बयान का उपयोग नहीं करता हूं, लेकिन यह पृष्ठभूमि में ठीक काम है, यह एक तरह के बयान के साथ क्वेरी में अनुवादित है।


आपका उत्तर स्वीकृत उत्तर (7 साल पहले दिया गया) या अन्य उत्तरों से अलग कैसे है? क्या मूल्य जोड़ता है?
डेविड फेरेंस्की रोगोजान

1
@DawidFerenczy यह उत्तर "बार में foo से" क्वेरी सिंटैक्स के साथ काम करता है, और स्वीकृत एक नहीं करता है।
20

1

यह कोशिश करो, यह मेरे लिए ठीक काम करता है

from record in context.Organization where record.Hierarchy.Contains(12) select record;


0

शामिल Linq में प्रयोग किया जाता है, वैसे ही जैसे की तरह एसक्यूएल में प्रयोग किया जाता है।

string _search="/12/";

। । ।

.Where(s => s.Hierarchy.Contains(_search))

आप अपनी SQL स्क्रिप्ट Linq में निम्नानुसार लिख सकते हैं:

 var result= Organizations.Join(OrganizationsHierarchy.Where(s=>s.Hierarchy.Contains("/12/")),s=>s.Id,s=>s.OrganizationsId,(org,orgH)=>new {org,orgH});

0

LINQ में "SQL लाइक" मेथड की राह देख रहे लोग मेरे लिए यहां कैसे आते हैं, इसके लिए मेरे पास कुछ ऐसा है जो बहुत अच्छा काम कर रहा है।

मैं ऐसे मामले में हूं जहां मैं कॉलम को बदलने के लिए डेटाबेस को किसी भी तरह से बदल नहीं सकता। इसलिए मुझे इसे करने के लिए अपने LINQ में एक रास्ता खोजना होगा।

मैं हेल्पर मेथड SqlFunctions.PatIndexविच का उपयोग कर रहा हूँ असली SQL LIKE ऑपरेटर के समान।

पहले मुझे कुछ हासिल करने के लिए खोज मूल्य में सभी संभव विकृति विज्ञान (एक शब्द जो मैंने अभी सीखा है) की गणना करने की आवश्यकता है:

déjà     => d[éèêëeÉÈÊËE]j[aàâäAÀÂÄ]
montreal => montr[éèêëeÉÈÊËE][aàâäAÀÂÄ]l
montréal => montr[éèêëeÉÈÊËE][aàâäAÀÂÄ]l

और फिर छूट के लिए LINQ में:

var city = "montr[éèêëeÉÈÊËE][aàâäAÀÂÄ]l";
var data = (from loc in _context.Locations
                     where SqlFunctions.PatIndex(city, loc.City) > 0
                     select loc.City).ToList();

तो मेरी जरूरतों के लिए मैंने एक हेल्पर / एक्सटेंशन विधि लिखी है

   public static class SqlServerHelper
    {

        private static readonly List<KeyValuePair<string, string>> Diacritics = new List<KeyValuePair<string, string>>()
        {
            new KeyValuePair<string, string>("A", "aàâäAÀÂÄ"),
            new KeyValuePair<string, string>("E", "éèêëeÉÈÊËE"),
            new KeyValuePair<string, string>("U", "uûüùUÛÜÙ"),
            new KeyValuePair<string, string>("C", "cçCÇ"),
            new KeyValuePair<string, string>("I", "iîïIÎÏ"),
            new KeyValuePair<string, string>("O", "ôöÔÖ"),
            new KeyValuePair<string, string>("Y", "YŸÝýyÿ")
        };

        public static string EnumarateDiacritics(this string stringToDiatritics)
        {
            if (string.IsNullOrEmpty(stringToDiatritics.Trim()))
                return stringToDiatritics;

            var diacriticChecked = string.Empty;

            foreach (var c in stringToDiatritics.ToCharArray())
            {
                var diac = Diacritics.FirstOrDefault(o => o.Value.ToCharArray().Contains(c));
                if (string.IsNullOrEmpty(diac.Key))
                    continue;

                //Prevent from doing same letter/Diacritic more than one time
                if (diacriticChecked.Contains(diac.Key))
                    continue;

                diacriticChecked += diac.Key;

                stringToDiatritics = stringToDiatritics.Replace(c.ToString(), "[" + diac.Value + "]");
            }

            stringToDiatritics = "%" + stringToDiatritics + "%";
            return stringToDiatritics;
        }
    }

यदि आप में से किसी के पास इस पद्धति को बढ़ाने का सुझाव है, तो मैं आपको सुनने के लिए तैयार रहूंगा।


आपका उदाहरण मूल रूप से एक घर का बना उच्चारण असंवेदनशील टकराव है। मुझे एक बार एक ऐसी परियोजना से निपटना पड़ा, जहां प्रत्येक और हर क्वेरी एक फिल्टर के माध्यम से चली गई जो कि एक उचित कोलाजेशन स्वचालित रूप से किया जाएगा। आमतौर पर बेहतर दृष्टिकोण के लिए कृपया stackoverflow.com/a/2461550/1736944 देखें । डेटाबेस, तालिका और / या क्षेत्र के लिए उचित टकराव को उचित समझा। (जगह में एक उचित
टकराव के

0

रास्ता देर से, लेकिन मैं इसे एसक्यूएल शैली वाइल्डकार्ड्स का उपयोग करते हुए स्ट्रिंग तुलना करने में सक्षम होने के लिए एक साथ फेंक दिया:

public static class StringLikeExtensions
{
    /// <summary>
    /// Tests a string to be Like another string containing SQL Like style wildcards
    /// </summary>
    /// <param name="value">string to be searched</param>
    /// <param name="searchString">the search string containing wildcards</param>
    /// <returns>value.Like(searchString)</returns>
    /// <example>value.Like("a")</example>
    /// <example>value.Like("a%")</example>
    /// <example>value.Like("%b")</example>
    /// <example>value.Like("a%b")</example>
    /// <example>value.Like("a%b%c")</example>
    /// <remarks>base author -- Ruard van Elburg from StackOverflow, modifications by dvn</remarks>
    /// <remarks>converted to a String extension by sja</remarks>
    /// <seealso cref="/programming/1040380/wildcard-search-for-linq"/>
    public static bool Like(this String value, string searchString)
    {
        bool result = false;

        var likeParts = searchString.Split(new char[] { '%' });

        for (int i = 0; i < likeParts.Length; i++)
        {
            if (likeParts[i] == String.Empty)
            {
                continue;   // "a%"
            }

            if (i == 0)
            {
                if (likeParts.Length == 1) // "a"
                {
                    result = value.Equals(likeParts[i], StringComparison.OrdinalIgnoreCase);
                }
                else // "a%" or "a%b"
                {
                    result = value.StartsWith(likeParts[i], StringComparison.OrdinalIgnoreCase);
                }
            }
            else if (i == likeParts.Length - 1) // "a%b" or "%b"
            {
                result &= value.EndsWith(likeParts[i], StringComparison.OrdinalIgnoreCase);
            }
            else // "a%b%c"
            {
                int current = value.IndexOf(likeParts[i], StringComparison.OrdinalIgnoreCase);
                int previous = value.IndexOf(likeParts[i - 1], StringComparison.OrdinalIgnoreCase);
                result &= previous < current;
            }
        }

        return result;
    }

    /// <summary>
    /// Tests a string containing SQL Like style wildcards to be ReverseLike another string 
    /// </summary>
    /// <param name="value">search string containing wildcards</param>
    /// <param name="compareString">string to be compared</param>
    /// <returns>value.ReverseLike(compareString)</returns>
    /// <example>value.ReverseLike("a")</example>
    /// <example>value.ReverseLike("abc")</example>
    /// <example>value.ReverseLike("ab")</example>
    /// <example>value.ReverseLike("axb")</example>
    /// <example>value.ReverseLike("axbyc")</example>
    /// <remarks>reversed logic of Like String extension</remarks>
    public static bool ReverseLike(this String value, string compareString)
    {
        bool result = false;

        var likeParts = value.Split(new char[] {'%'});

        for (int i = 0; i < likeParts.Length; i++)
        {
            if (likeParts[i] == String.Empty)
            {
                continue;   // "a%"
            }

            if (i == 0)
            {
                if (likeParts.Length == 1) // "a"
                {
                    result = compareString.Equals(likeParts[i], StringComparison.OrdinalIgnoreCase);
                }
                else // "a%" or "a%b"
                {
                    result = compareString.StartsWith(likeParts[i], StringComparison.OrdinalIgnoreCase);
                }
            }
            else if (i == likeParts.Length - 1) // "a%b" or "%b"
            {
                result &= compareString.EndsWith(likeParts[i], StringComparison.OrdinalIgnoreCase);
            }
            else // "a%b%c"
            {
                int current = compareString.IndexOf(likeParts[i], StringComparison.OrdinalIgnoreCase);
                int previous = compareString.IndexOf(likeParts[i - 1], StringComparison.OrdinalIgnoreCase);
                result &= previous < current;
            }
        }

        return result;
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.