2017-11-14 7 views
1

を検索する: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を検索します。

私は、Entity Frameworkを使用して、次のLINQクエリを持っています。

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

しかし、文字列 "RIC JONは" 何も見つかりません。

私はlinqクエリがSQLクエリと同じように動作するように見えません。

+0

'(employee.first_name +" "+ employee.last_name).Contains(matchString)'(およびその逆)? – CodeCaster

+0

同じ問題。それは部分的に期待通りにファーストネームにマッチしますが、文字列にスペースを入れると、それは完全に見つけられなくなります。 –

+0

できれば[類似機能](https://stackoverflow.com/a/46975884/861716)を使用してください。 –

答えて

0

SQLでは、実際には、指定した "ric jon"でサンプリングしたレコードは見つかりません。あなたが求めているのは、IMHOがバックエンドでネイティブにサポートされていない関数を必要とする特別なフィルタです(あなたはバックエンドを指定しませんでしたが、少なくとも私はこれをネイティブでサポートするバックエンドを知りません)。このような何かに働くだろう(あなたがローカルに従業員のレコードを取得していることに注意してください、これはバックエンドのレベルで行われていません):

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)))); 
+1

すべてのレコードをクライアント側でフィルタリングし、検索語を2語に限定するのは良い解決策ではありません。 – CodeCaster

+0

@ CodeCaster、2ワードの検索用語は私のものではなくOPのアイデアです。レコードクライアント側を取得する必要のないコードも提供しました。私が思っていたコードの2番目の部分です。 –

関連する問題