Ktouth Brand. on Web

け〜くんこと K.Ktouth のだらだらした日常と突発的に作るプログラムや読み物とかの雑多サイト



[2009年10月11日]

EF と SqlCe で文字列の比較が出来ないバグ

2009年10月12日 03:41更新 筆者:K.Ktouth

なぜかうまく行かず、少々困ったので後々のために自分メモ。

EFとSqlCeの組み合わせにおいて、テーブル内の文字列のカラムを元に絞り込んでカウントアップしようとした際、なぜか「ntext および image データ型は、HAVING、GROUP BY、オン、または句のこれらのデータ型は、LIKE を使った場合を除くまたは NULL の述語は WHERE を使用できません。」と言った例外が発生することが。

調べると、どーも既知のバグらしいです。

要は与えられた文字列情報を「文字列として正しく認識せずにクエリ化しようとしている」?ために起こっているらしいのです。
上記ページより修正コードは手に入るようですが、Microsoft Updateで自動配布されていないあたり、まだ検証段階のような気がします。上記ページも機械翻訳で読みづらいし(笑)

一応、修正プログラムを使わずにこの問題を回避する方法を提示しておきます。
とあるテーブル Address があり、Id を数値によるキー、Name を文字列で定義し、両方とも Unique 指定してあるとします。
で、特定の Id 以外で同じ Name を持つレコードを抽出したいとき。

var query = from i in context.Address
       .Where("it.Name = CAST(@at AS System.String)", new ObjectParameter("at", this.Name))
      where i.Id != this.Id
      select i;
if (query.Any()) { throw new ApplicationError("同名の住所が存在します"); }

ポイントは2行目。
普通に Linq で「where i.Name == this.Name」みたいな書き方をすると上記のエラーが出ます。
当然 Where() 拡張メソッドで素直な構文で書いても同様ですが、上記のように一端 CAST AS を使うことで内部で強制的に文字列として認識するように仕向けています。
System.Stringとしなきゃならないのが微妙(笑)
拡張メソッド形式でのパラメータ名は重複していくので、なるべくもっと一意的でかつ他の所で使ってもかぶらないような名前にするのがお勧めです。

本日のリンク元
アンテナ
その他のリンク元
検索