Ktouth Brand. on Web

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



[2008年01月05日]

LinqとSQLCeの落とし穴

2008年01月05日 19:19更新 筆者:K.Ktouth

Visual Studio 2008 Standard Edition アップグレード(AA)

昨日の日記で、うまくエントリの検証が出来ないといった点はどうにか解決したものの、その直後に別の部分でトラブル発生。

なんとエントリのデータ更新(UPDATE)のクエリ発行に失敗するんです。
特に変な事はしてないはずだし、ドコでトラブっているのかわからない状況。
半日かけてようやく原因究明に成功、解決しましたが……Linq と SQLCeの組み合わせに若干の不安を感じる結果に。

(詳細は以下に)

UPDATE SQL文がおかしい!?

コードで表すと……

void TestCode() {
 SampleDataContext dc = new SampleDataContext(...);
 dc.Log = Console.Error;

 Foo foo = dc.Foo.First();
 Console.WriteLine("foo.Bar.text = '{0}'", foo.Bar.text);

 foo.Bar = dc.Bar.First(b => b.id == 6);
 Console.WriteLine("foo.Bar.text = '{0}'", foo.Bar.text);

 dc.SubmitChanges();
}

こんな感じです。アソシエーションプロパティを別のものに変えているだけ。
で、この最後のSubmitChanges()で例外が発生するんです。
調べると……原因を発見。UPDATE の SQL文の WHERE 節が「 0 = 1 」になっていたんです。更新する該当行がない(必ず条件が偽になる)んじゃ例外も発生するってもんです。

が。
SQL文はLinq が自動生成するため、簡単にはいじれません。と言うかこのレベルで独自SQL文を書く必要があるなら意味がありません。

どうしてこんな変なSQL文になるんだろうか? バグ?

わかってみれば

……
……
と、半日悩んで一端プロジェクトをバックアップ。構成要素を一つずつ削って問題が出ないところまで削っていくと。
Linq to SQL デザイナでのFoo クラスのプロパティの一部に設定ミスを発見びっくり
「いくつかのNULL許容プロパティで CanBeNull 属性が False になっていた」のが原因だったんです。
つまりは、「テーブル定義を正確に書き写していなかった、と。
そんなケアレスミスで半日費やしてしまうとは……わーん

Linqは便利ですし、SQLCeも軽くてサーバーも不要というおいしいものですが。
デザイナが非対応というのはヒューマンミスを呼びやすいので、出来ればアップデートで対応して欲しいものです……

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