407

我有一个 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/% 来搜索它。

我的问题是,什么是 Linq 或 .NET 相当于使用百分号?

4

14 回答 14

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

您也可以使用.StartsWith().EndsWith()

于 2009-05-07T16:45:50.067 回答
259

用这个:

from c in dc.Organization
where SqlMethods.Like(c.Hierarchy, "%/12/%")
select *;
于 2010-06-15T13:48:19.973 回答
43

我假设您使用的是 Linq-to-SQL*(请参阅下面的注释)。如果是这样,请使用 string.Contains、string.StartsWith 和 string.EndsWith 来生成使用 SQL LIKE 运算符的 SQL。

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 Entity Framework (EF / L2E),请注意它不会进行与 Linq-to-SQL 相同的转换。尽管 L2S 进行了正确的转换,但 L2E v1 (3.5) 将转换为 t-sql 表达式,该表达式将强制对您正在查询的表进行全表扫描,除非您的 where 子句或连接过滤器中有另一个更好的鉴别器。
更新:这在 EF/L2E v4 (.net 4.0) 中已修复,因此它会像 L2S 一样生成 SQL LIKE。

于 2009-05-07T16:46:19.503 回答
29

如果您使用的是 VB.NET,那么答案将是“*”。这是您的 where 子句的样子...

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

注意:“*”匹配零个或多个字符。这是针对 Like 运算符的 msdn 文章

于 2009-05-07T17:34:39.870 回答
8

好吧 indexOf 也适合我

var result = from c in SampleList
where c.LongName.IndexOf(SearchQuery) >= 0
select c;
于 2011-10-04T11:56:52.160 回答
7

.NET 核心现在有EF.Functions.Like

  var isMatch = EF.Functions.Like(stringThatMightMatch, pattern);
于 2018-09-16T10:23:36.687 回答
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;
}
于 2016-08-08T12:48:57.277 回答
3

如果您不匹配数字字符串,最好有常见的情况:

.Where(oh => oh.Hierarchy.ToUpper().Contains(mySearchString.ToUpper()))
于 2016-11-25T00:19:18.953 回答
2

我总是这样做:

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

我知道我不使用 like 语句,但它在后台工作正常,这是翻译成带有 like 语句的查询。

于 2016-02-16T13:19:13.587 回答
2
System.Data.Linq.SqlClient.SqlMethods.Like("mystring", "%string")
于 2018-11-30T14:07:54.380 回答
1

试试这个,这对我来说很好

from record in context.Organization where record.Hierarchy.Contains(12) select record;
于 2015-07-15T03:20:59.270 回答
0

Contains用于 Linq,就像Like用于 SQL 一样。

string _search="/12/";

. . .

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

您可以在 Linq 中编写 SQL 脚本,如下所示:

 var result= Organizations.Join(OrganizationsHierarchy.Where(s=>s.Hierarchy.Contains("/12/")),s=>s.Id,s=>s.OrganizationsId,(org,orgH)=>new {org,orgH});
于 2016-09-23T11:10:48.210 回答
0

对于那些像我一样在 LINQ 中寻找“SQL Like”方法的方法的人来说,我有一些非常好的东西。

我处于无法以任何方式更改数据库以更改列排序规则的情况。所以我必须在我的 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();

所以为了我的需要,我写了一个 Helper/Extension 方法

   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;
        }
    }

如果你们中的任何人有改进这种方法的建议,我会很高兴听到你的声音。

于 2017-10-05T18:26:52.027 回答
0

很晚了,但我把它放在一起以便能够使用 SQL Like 样式通配符进行字符串比较:

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="https://stackoverflow.com/questions/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;
    }
}
于 2020-05-11T19:08:07.600 回答