私は、誰かがユーザーの名前や名前でユーザーを検索できるようにするUIを作成しています。たとえば、名に「Mike」、姓に「Jo」と入力すると、「Mike Jones」、「Mike Johnson」、「MikeJobs」が返されます。この検索には、次のLINQステートメントを使用します。
var users = (from u in context.TPM_USER
where u.LASTNAME.ToLower().Contains(LastName.ToLower())
&& u.FIRSTNAME.ToLower().Contains(FirstName.ToLower())
select u);
(大文字と小文字を区別しないlike句を実行するためのより良い方法がある場合とない場合がありますが、これは機能するようです)
問題は、ユーザーが名または姓を入力した後、他のフィールドを空のままにした場合です。名に「Mike」と入力し、[Last Name]フィールドを空白のままにすると、名前に関係なくすべてのMikeを返します。上記のクエリは、両方のフィールドに少なくとも何かが入力されていない限り、結果を返しません。
私は試した:
var users = (from u in context.TPM_USER
where (LastName == "" || u.LASTNAME.ToLower().Contains(LastName.ToLower()))
&& (FirstName == "" || u.FIRSTNAME.ToLower().Contains(FirstName.ToLower()))
select u);
ただし、両方のフィールドに入力しない限り、結果は得られません。私はデバッガーの下でそれLastName == ""
が確かに真実であることを確認しました。
アップデート:
もう少しデバッグを行いましたが、これは実際にはOracleの問題です。生成されるクエリは次のとおりです。
--Replaced the field list with * for brevity
SELECT * FROM TPMDBO.TPM_USER "Extent1"
WHERE (('jones' = '') OR ((INSTR(LOWER("Extent1".LASTNAME), LOWER('jones'))) > 0)) AND (('' = '') OR ((INSTR(LOWER("Extent1".FIRSTNAME), LOWER(''))) > 0))
一見正しいように見えます。ただし、Oracleはフレーズを正しく短絡していないようです('' = '')
。実際、私がそうするなら:
select * from TPM_USER where '' = ''
行がゼロになります。このクエリをどのように作成するかを知るには、Oracleの専門家では不十分ですが、どちらにしても、EntityFrameworkの方言のバグです。