16

私はこれを検索したい:Linq to Entities(EF 4.1):途中でワイルドカードを使用してSQL LIKEを実行する方法( '%term%term%')?

Post Cereal 

と、この取得:ワイルドカードは空白になり

Post Honey Nut Cereal 

を。

SPLITと一連のANDsとContains()を実行して、各用語のLinq式を仕様オブジェクトとして翻訳することはできますが、SQLに送信される用語にワイルドカードを使用する方法はありません? Linq to SQLのSQL関数を調べましたが、Linq to Entitiesの内容がわかりません。

私はこのような何かをしたいと思います:

term = '%' + term.Replace(' ', '%') + '%'; 
db.table.where(p => System.Data.Objects.SqlClient.SqlFunctions 
        .SqlMethods.Like(p.fieldname, term)); 

任意の提案を?

答えて

43

私はあなたがSqlFunctions.PatIndexを使用することができます信じる:

dt.Table.Where(p => SqlFunctions.PatIndex(term, p.fieldname) > 0); 

SqlFunctions.PatIndexはSQL LIKE演算子と同じ動作をします。

  • ゼロ文字以上の任意の文字列:それはを含むすべての標準的なワイルドカード文字をサポートしています。
  • _(アンダースコア)任意の1文字。
  • []指定した範囲([a-f])またはセット([abcdef])内の任意の1文字。
  • [^]指定された範囲([^ a-f])またはセット([^ abcdef])内にない任意の単一の文字。

SqlMethods.Likeは(MVCコントローラ内を含む)が利用できないときSqlFunctions.PatIndexがしばしば利用可能である

+1

これ以上の投票が必要です。これはあまり複雑でなくても私にとって完璧に機能しました。 –

+0

ジム博士は正しいです、数時間の解決策を探していましたが、これは私が見つけた最も単純なものです。 – user1841243

+0

私はこれを.NETで直接試してみましたが、どちらもうまくいきませんでした。 EF 5、.NET 4.5およびVS 2012の使用 – Matt

5

おそらく、LINQをバイパスし、エンティティSQLフィルタを使用する方が簡単です:

var query - db.table.Where("TRIM(fieldname) LIKE @pattern"); 
query.Parameters.Add(new ObjectParameter("pattern", term)); // term == "%what%ever%" 

queryの種類はIQueryable<TEntity>ので、あなたはさらにLINQ演算子を適用することができますを実装しています。

+0

私はこれをLINQPadで試していますが、この例外を受け取ります: 'EntitySqlException: 'BusinessName'を現在のスコープまたはコンテキストで解決できませんでした。参照されているすべての変数がスコープ内にあり、必要なスキーマがロードされていて、その名前空間が正しく参照されていることを確認します.' "BusinessName"はフィルタリングしようとしている列です。これを過ぎる方法を理解できません。 –

+0

@adriftコンテキスト情報を使ってLINQPadを設定する必要があります。私はそれをほとんど使用しないので、実際には役に立ちません(IIRCは、単にコンテキストとエンティティタイプを持つアセンブリを参照しました)。 – Richard

+1

Entity SQLを使用することは、これを行う唯一の方法です.L2Eは、このタイプのワイルドカード検索をサポートしていません。あなたの問題を解決するには 'it.BusinessName'を使ってみてください。 ESQLの列は接頭語でなければならず、 'it'はデフォルト接頭辞です - [here](http://stackoverflow.com/questions/6202036/entity-framework-v4-1-like/6202346#6202346) 。 –

0

だけit.BusinessNameに関するラディスラフさんのコメントを明確にします。私は彼が指しているものは、フィールド名の先頭に.itという接頭辞が付いていると思います。上記の解決策はwhere句のフィールド名の前にit.という接頭辞がある限り機能します。また、私の場合はTRIM()は必要ありませんでした。

var query - db.table.Where("it.fieldname LIKE @pattern"); 
query.Parameters.Add(new ObjectParameter("pattern", term)); // term == "%what%ever%" 

これはOracleデータベースに対して完全に機能しました。

関連する問題