I have a procedure in SQL that I am trying to turn into Linq:
SELECT O.Id, O.Name as Organization
FROM Organizations O
JOIN OrganizationsHierarchy OH ON O.Id
.NET core now has EF.Functions.Like
For those how tumble here like me looking for a way to a "SQL Like" method in LINQ, I've something that is working very good.
I'm in a case where I cannot alter the Database in any way to change the column collation. So I've to find a way in my LINQ to do it.
I'm using the helper method SqlFunctions.PatIndex
witch act similarly to the real SQL LIKE operator.
First I need enumerate all possible diacritics (a word that I just learned) in the search value to get something like:
déjà => d[éèêëeÉÈÊËE]j[aàâäAÀÂÄ]
montreal => montr[éèêëeÉÈÊËE][aàâäAÀÂÄ]l
montréal => montr[éèêëeÉÈÊËE][aàâäAÀÂÄ]l
and then in LINQ for exemple:
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();
So for my needs I've written a Helper/Extension method
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;
}
}
If any of you have suggestion to enhance this method, I'll be please to hear you.
Use such code
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;
}
Use this:
from c in dc.Organization
where SqlMethods.Like(c.Hierarchy, "%/12/%")
select *;
If you are using VB.NET, then the answer would be "*". Here is what your where clause would look like...
Where OH.Hierarchy Like '*/12/*'
Note: "*" Matches zero or more characters. Here is the msdn article for the Like operator.
I do always this:
from h in OH
where h.Hierarchy.Contains("/12/")
select h
I know I don't use the like statement but it's work fine in the background is this translated into a query with a like statement.