String.StartsWith not working with tilde (“~”) characters LINQ to SQL?

后端 未结 3 1431
眼角桃花
眼角桃花 2021-01-19 18:25

For some reason, my call to IEnumerable.Where() using String.StartsWith() appears to be giving different results depending on whether it\'s being used in LINQ-to-SQL or stan

3条回答
  •  醉话见心
    2021-01-19 19:19

    At Konamiman's suggestion I checked the log to see what SQL was being executed. Here's (a munged example of) what I got.

    The first call executes:

    SELECT [t0].[ID], [t0].[Name]
    FROM [dbo].[MyEntity] AS [t0]
    

    That makes sense, as the filtering is happening on the client-side, so we need to query for all rows.

    The second call executes:

    SELECT COUNT(*) AS [value]
    FROM [dbo].[MyEntity] AS [t0]
    WHERE [t0].[Name] LIKE @p0 ESCAPE '~'
    

    So, Jon Skeet was on the right track; I'm getting the problem because I happen to have a tilde in my data/query condition. This causes LINQ-to-SQL to mark it as an escape character, and thus it doesn't get used in the search. This MSDN thread does a decent job of explaining why; it appears to be a bug in the LINQ-to-SQL code.

    The suggested workaround is to use LINQ's SQLMethods.Like() method to change the escaping character away from "~", like so:

    var direct = MyDataContext.MyEntities.Where(entity => SQLMethods.Like(entity.Name, "~Test: My Test String%", "!");
    // direct.Count() now returns 5 as expected
    

    This works, but unfortunately this is a LINQ-to-SQL only solution. If you try it on the LINQ-to-Object version, you get this error:

    System.NotSupportedException : Method 'Boolean Like(System.String, System.String, Char)' 
    cannot be used on the client; it is only for translation to SQL.
    

    The same thing happens when using AsEnumerable() as Jon Skeet suggested.

    I tried wrapping my StartsWith call in a method and using StartsWith with a StringComparisonOption, but these don't work on the LINQ-to-SQL side because they're not SQL-translatable. (And thus my earlier assumption about the Where() method was incorrect).

    So: it looks like (until this bug is fixed) you cannot have a searching function that both works with tilde characters and is agnostic about the underlying flavour of LINQ. (If there is a method, please be sure to post it).

提交回复
热议问题