LINQ查询以搜索具有部分名称的用户

时间:2017-11-14 12:26:31

标签: sql entity-framework linq

我有这个SQL查询:

SELECT 
    *
FROM
    employeeTable
WHERE 
    (
    concat(first_name, ' ', last_name) like concat('%', replace(@MatchString, ' ', '%'), '%')
        or
    concat(last_name, ' ', first_name) like concat('%', replace(@MatchString, ' ', '%'), '%')
    )

通过使用部分字符串搜索用户,通过使用部分值搜索姓名和姓氏,它可以完美地工作。例如:

" ric jon"会找到Rick Jones,Richard Jonesy和Jonathan Prichter。

我有以下Linq查询,使用实体框架:

from employee in context.Employee
                    where employee.first_name.Contains(matchString)
                    || employee.last_name.Contains(matchString)
                    select employee

但字符串" ric jon"找不到任何东西。

我似乎无法使该linq查询与SQL查询相同。

1 个答案:

答案 0 :(得分:0)

SQL实际上不会找到您使用给定“ric jon”采样的记录。你要求的是一个特殊的过滤器,恕我直言需要一个后端本身不支持的功能(你没有指定你的后端,但至少我不知道一个本地支持它的后端)。这样的东西会起作用(注意你将Employee记录带到本地,这不是在后端级别完成的):

Func<Employee, string[], bool> match = (emp, _parts) => {
     return 
     ((emp.FirstName.IndexOf(_parts[0],StringComparison.CurrentCultureIgnoreCase  ) != -1) &&
     (_parts.Length == 1 || emp.LastName.IndexOf(_parts[1], StringComparison.CurrentCultureIgnoreCase) != -1)) ||
     ((_parts.Length == 1 || emp.FirstName.IndexOf(_parts[1], StringComparison.CurrentCultureIgnoreCase) != -1) &&
     (emp.LastName.IndexOf(_parts[0], StringComparison.CurrentCultureIgnoreCase) != -1));
};

string search = "ric jon";
var result = context.Employee.AsEnumerable()
              .Where(n => match(n, search.Split()));  

更新

您可以使用许多后端支持的这个:

string search = "ric jon";
string[] parts = search.ToLowerInvariant().Split();
string p1 = parts.Length < 1 ? "" :parts[0];
string p2 = parts.Length < 2 ? "" :parts[1];

var result = context.Employee.Where(n => 
    ((n.FirstName.ToLowerInvariant().Contains(p1) &&
     n.LastName.ToLowerInvariant().Contains(p2))) ||
     ((n.FirstName.ToLowerInvariant().Contains(p2) &&
     n.LastName.ToLowerInvariant().Contains(p1))));