|
by developer-adjust 検索
リンク
タグ
AJAX
Selenium
ライトニングトーク
Haskell
TechEd
ASP.NET Dynamic Data
ADO.NET Entity Framework
LINQ
ASP.NET
Apache
Visual Studio
SQL Server
統合Windows認証
Plone
Ruby
ASP.NET MVC
.NET
C#
NUnit
スレッドプール
カテゴリ
最新のコメント
最新のトラックバック
以前の記事
|
2009年 10月 27日
早いものでもう去年のエントリの話なのだが、SQLite 3 をデータストアに採用した .NET アプリを Visual Studio 上で開発する話について。
ADO.NET 2.0 Provider for SQLite を使えば、Visual Studio のデータベースデザイナ支援も受けられ、ADO.NET Entity Framework や、ASP.NET DynamicData Web アプリが作れますよ、ということなのだが、一点、どういうわけか、Visual Web Developer 2008 Express(SP1) (以下、VWD)では、データベースデザイナが動作しない。 VWD のサーバーエクスプローラで SQLite データベースファイルへの接続を追加しようとすると、次の例外が発生してしまうのだ。 ファイルまたはアセンブリ 'Microsoft.VisualStudio.Data, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'、またはその依存関係の 1 つが読み込めませんでした。見つかったアセンブリのマニフェスト定義はアセンブリ参照に一致しません。 (HRESULT からの例外: 0x80131040)基本的に、VWD は使っておらず、Visual Studio 2008 Pro SP1 ではちゃんと使えていたので、その後ほったらかしにしていたのだが、つい先日、VWD でもちゃんと ADO.NET Provider for SQLite のデータベースデザイナ支援が機能するようできた。 気づいてみればなんのことはなかった。 Microsoft.VisualStudio.Data アセンブリについて、"バージョンリダイレクト" をアプリケーション構成ファイルに記述しておけばよいのだ。 すなわち、VWD にも ver.9.0.0.0 の Microsoft.VisualStudio.Data アセンブリは同梱されているわけで、上記 SQLite のデザイナがコケてしまうのは、存在しない ver.8.0.0.0 の同アセンブリを読み込もうとするからに過ぎないのである。 アプリケーション構成ファイルにて、VWD が ver.8.0.0.0 を読み込もうとしたら、ver.9.0.0.0 を読み込むように明示的に指示しておけばよいわけだ。 VWD の場合だと、実行ファイルは C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\VWDExpress.exe なので、アプリケーション構成ファイルは、同じフォルダにすぐ見つかる、VWDExpress.exe.config となる。 あと、同梱されている Microsoft.VisualStudio.Data アセンブリをエクスプローラから検索して探し当て、Reflector.NET とかなにかの手段でアセンブリバージョン(ファイルバージョンではなく)が 9.0.0.0 であることを確認しておく。 で、VWDExpress.exe.config をテキストエディタで開くと、実はすでに runtime セクションが記載済みであるのが見つかる。 Microsoft.VSDesigner などは、すでに、ver.8.0.0.0 から ver.9.0.0.0 を参照するようバージョンリダイレクトの指示が書かれているのであった。 これにならって、Microsoft.VisualStudio.Data についても、バージョンリダイレクトの指示を追記する。 具体的には、runtime/assemblyBinding ノードの最後の子要素として、下記を追記する。 <dependentAssembly> <assemblyIdentity name="Microsoft.VisualStudio.Data" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <bindingRedirect oldVersion="8.0.0.0" newVersion="9.0.0.0" /> </dependentAssembly> 以上で設定は完了。 VWD を起動して、サーバーエクスプローラから SQLite データベースファイルへの接続を追加すると、無事、データベースデザイナが機能するようになった。 以下、証拠写真。 サーバーエクスプローラから、接続の追加を行い、データソースとして SQLite を選択。 ![]() VWD でも、ちゃんと SQLite の「接続の追加」ダイアログが表示される。 ![]() サーバーエクスプローラに接続の追加成功。テーブルのデザインもちゃんとできる。 ![]() テーブルレコードの追加/変更/削除も機能。 ![]() ADO.NET Entity Framework のデザイナも OK。 ![]() このあと、この ADO.NET Entity Framework でデザインしたエンティティクラスを使って、ASP.NET MVC で簡単な CRUD アプリの作成・実行を試してみたが、無事、完遂できた。 どうしても故あって、Express 版の Visual Studio を使っている場合でも、これにて SQLite を存分に活用できるようになった。 Tags:SQLite Visual Studio 2009年 10月 01日
前回、関数プログラミングのリハビリがてら、Haskell で Fizz-Buzz 問題を解いてみたのだが、まぁ、問題が簡単すぎで、あんまり "関数型言語ならでは" という雰囲気がでなかった。
Haskell の構文を思い出すのには役だったが、リハビリというにはちょっとだったかも。 そんな思いのせいか、無性に Prolog でも Fizz-Buzz 問題を解いてみたくなった。 使った処理系は P#。 trans(N,fizzBuzz) :- trans(N,fizz), trans(N,buzz). trans(N,fizz) :- 0 is N mod 3. trans(N,buzz) :- 0 is N mod 5. trans(N,N). do(101). do(N) :- trans(N,Result), write(Result), nl, N2 is N + 1, do(N2). こんな感じですかね。 これで、 ?- do(1). と "問い合わせ" すると、コンソールに結果表示される。 「1から100まで」という、いわゆるループというか、あるいは、[1,2,3,...,100] というリストの生成とかを Prolog ではどうやるのがいいのか、知識不足と経験不足でよくわからなかったため、自己流で再帰で書いた。 Prolog ならではの雰囲気は、前半の trans 述語。 "N が fizz でも buzz でもある場合は fizzBuzz である" とか、"上記いずれにも該当しない場合は N は N である" など、論理プログラミングというか、ユニフィケーションおもしろい、といったところである。 Tags:Prolog 2009年 09月 30日
関数プログラミングもとんとご無沙汰だったので、リハビリから。
とういうことで、Fizz-Buzz 問題を Haskell で解いてみる。 main = putStrLn $ unlines $ map fizzBuzz [1..100] where fizzBuzz n | mod n 3 == 0 && mod n 5 == 0 = "FizzBuzz" | mod n 3 == 0 = "Fizz" | mod n 5 == 0 = "Buzz" | otherwise = show n 1から100までの数値のリストに対して、各要素ごとに fizzBuzz 関数を適用。 fizzBuzz 関数は文字列を返すので、結果、map 関数の戻り値は "文字列のリスト" となる。 これを、改行を区切り文字として単一の文字列に連結 ( unlines ) して、結果をコンソールに表示 ( putStrLn ) ... するアクションを返して main の評価により実行。 いっぽうの fizzBuzz 関数の定義は、ガード ( | ) によって、引数の数値 n が3の倍数か5の倍数かに応じて "Fizz" や "Buzz" などの文字列を返し、いずれの倍数でもない場合は、数値 n をそのまま文字列に書式化 ( show ) して返す。 とまぁ、こんな感じか? ガードの判定が冗長だな。"Fizz" と "Buzz" を連結して "FizzBuzz" にするほうがいいのかも。 F# や Prolog ではどう書くのだろう、Fizz-Buzz問題。 Tags:Haskell 2009年 09月 29日
LINQ to SQL や ADO.NET Entity Framework / LINQ to Entity などの登場により、コード上で文字列として SQL 文を組み立ててクエリ発行、といった実装はめっきり減りつつあるのかもしれない。そもそもストアドプロシージャにすれよ、という話もあるが。
しかし、それでも、そんなアドホックなクエリを発行したい場面はゼロじゃない。 動的LINQなどでも WHERE 節を文字列で渡すことになるし、LINQ to SQL の .dtml を起こすほど大仰にやりたくないときだってある。 さてそんなとき、悩ましいのが、LIKE 演算子を使ったパターン検索。 SQL文を、 SELECT * FROM Hoge WHERE Foo LIKE @p0 として、パラメータ @p0 に "%Bar%" と指定してクエリ発行すれば、「列 Foo に "Bar" という文字列を含む行」が返されるわけだ。 しかし、「列 Foo に "%" という文字を含む行」を取得したい場合はどうする? 文字 "%" はすでに LIKE 演算子によるパターン検索上のワイルドカード文字である。 したがって、何らかのエスケープシーケンスが必要となるのが正解。 SQL文を、 SELECT * FROM Hoge WHERE Foo LIKE @p0 ESCAPE '~' とすれば、文字 "~" がエスケープ文字として機能するようになる。 よって、パラメータ @p0 に "%~%%" と指定してクエリ発行すればよい。 となると、残るは、どうやってパラメータ @p0 に渡す検索語句をエスケープ処理するか、だ。 ものすごく難しいわけではないのだろうが、自分でスクラッチでエスケープ処理を行うコードを自作するのもなんだかなー、と思ってしまう。 それに、この種のコードは、すでに実績のあるコードを再利用できるものなら再利用すべきだろう。 目をつけたのは LIQ to SQL のコード。 LINQ to SQL も、内部ではこのようなエスケープ処理を施した T-SQL 文をアドホックに組み立てて発行しているのだから、LINQ to SQL の内部をのぞき見れば、エスケープ処理をどうやっているのかわかるはず。 そう思い立って、ソースでもひもといてみようかとしたが、いやいや、はやる気持ちを抑えて、msdn library を少し眺めてみることにした。 そうしたところ、運良くすぐに目に飛び込んできたのが、System.Data.Linq.SqlClient.SqlHelpers クラス。 次のように、SqlHelpers クラスの static メソッドを呼び出してやれば、 SqlHelpers.GetStringContainsPattern("%", '~') "%~%%" という文字列が手に入る次第。 ワイルドカード文字 "%" をどこに挿入するかにあわせて、GetStringStartsWithPattern メソッドと、GetStringEndsWithPattern メソッドも用意されている。 "%" 以外の、"_" などのワイルドカード文字も組み合わせてより精緻な検索を行いたいときはさすがに SqlHelpers のメソッドでも歯が立たないが、しかし、上記 Contains/StartsWith/EndsWith の3パターンで事足りるのであれば、ちゃんと "_" などもエスケープされる。 SqlHelpers のこの3メソッド、万人向けじゃないかもしれないが、いざというときには必要となる "武器" だ。 2009年 09月 28日
本業多忙につき、とんと2ヶ月も無沙汰にしてしまったブログだが、ぼちぼちと再開。
リハビリがてら、軽めのネタから。 先々月の最後の投稿、「Internet Explorer 6 でのダウンロード時、既定のファイル名として日本語使うと16文字にカットされてしまう」の類似ネタである。 Webサーバーからの応答ヘッダに、content-disposition: attachment; filename=~ を指定することで、Internet Explorer (以下、IE) はじめ各種Webブラウザにダウンロードダイアログを表示させることができるのは周知のとおり。 特に IE においては、UTF-8エンコードされた文字列を、URLエンコードした形式で、filename=~ に指定してやれば、既定の保存ファイル名に日本語を指定することもできる。 そんな実装を、ASP.NET による Webアプリで実装していたら、とある日、不思議な現象を発見。 既定の保存ファイル名に空白を含む場合、なんと、IE のファイル保存ダイアログには、空白が "+" に化けたファイル名が表示されるのだ。 いや、"化ける" とは言ったが、厳密には、たしかに "+" は空白を URL エンコードした結果には違いない。 言い換えると、ほかの文字列(とくに日本語文字など)はちゃんとURLデコードされているのに、"+" だけはデコードされないようなのだ。 手元の環境では、IE 6 でも IE 8 でも現象は同じ。 まぁ、これはそういうものなんでしょう、IE の仕様なんでしょう。 ということで、空白をURLエンコードするには、"+" とする以外にもうひとつ、"%20" とすることもできる。 試しに、finelame=~ に "%20" を含む文字列を指定したところ、IE 6/IE 8 でも、ちゃんと %20 は空白にデコードされて、ファイル保存ダイアログに表示された。 しかししかし。 HttpUtility.UrlEncode メソッドを使って URL エンコードしていたのだが、どうも、このメソッドは空白を "+" ではなく "%20" にエンコードできるようなオプションはないらしい。 致し方ないので、 HttpUtility.UrlEncode(fileName).Replace("+", "%20"); というように、エンコード後の文字列に対して、愚直に string.Replace メソッドで置換を行うようにした。 なんだかなー、という気がしないでもないが、これにて収めることにした。 なお、某所から教えて頂いたところでは、CodePlex 上で公開されている、AntiXSS というライブラリを使えば、空白を "%20" で URL エンコードできるそうだ。 まだ使ったことはないが、ソースコードを見るに、 AntiXss.UrlEncode(string) でURLエンコードできるようなので、使い方に迷うことはなさそうだ。 こだわる向きは、AntiXSS ライブラリの採用を検討するのもよいかもしれない。 Tags:ASP.NET 2009年 07月 28日
時代的には今更の感もある、Internet Explorer 6 での話。
Webサーバーからの応答ヘッダに、content-disposition: attachment; filename=~ を指定することで、Internet Explorer にダウンロードダイアログを表示させることができるのは周知のとおり。 ダウンロードダイアログには、"filename=~" で指定したファイル名が既定で表示される。 ここで、特に Internet Explorer が相手の場合は、"filename=~" に UTF-8 で URLエンコードした文字列を指定すれば、日本語文字列であっても期待通りに正しくダウンロードダイアログに既定のファイル名を表示させることができる。 ところで、である。 なんと、Internet Explorer 6 では、"filename=~" に日本語指定した場合、たかだか 16 文字に刈り取られてしまうことが判明。 (これまで知らなかった...) いろいろ調査した結果、どうやら IE6 では、"filename=~" に指定したファイル名文字列が 最大150文字までに収まるよう、先頭を刈り取ってしまうらしい。 まぁ、150文字もあればじゅうぶん、という気もするが、ここで日本語ファイル名を指定した場合がちょっとひっかかってくる。 先に書いたとおり、UTF-8 で URL エンコードした場合、日本語文字は1文字が "%12%32%56" のように9文字になってしまう。 どうやら IE6 は、この、エンコードされた文字列に対して、150文字に刈り取りするようなのだ。 計算としては、ファイル名長上限 150 を 9 で割ると、16.666... ということで、日本語文字だけだとたしかに 16 文字に刈り取られてしまうわけだ。 ちなみに、Internet Explorer 8 の場合はそこまでひどいことはなく、すべて日本語文字だけの場合でも、202 文字だけに刈り取られるだけで済んだ。 (それでも、最近の Windows OS が許しているファイル名最大長 250文字よりも短くはなっているようだが) まぁ、そんなにまでして、ダウンロードファイル名の既定値に日本語使うことにこだわる必要があるのか? とか、今更 Internet Explorer 6 なのか? という指摘・議論もあるとは思うが、とりあえず。 ※ Internet Explorer 6 は、Windows XP Pro SP3 上で動作確認。 Internet Explorer 8 は、Windows Vista Busioness SP2 上で動作確認。 また、上記で "日本語文字" と書いてあるが、これはようするに、UTF-8 でエンコードした際に2バイト以上でエンコードされる文字であれば日本語である必要はないし、さらに言えば、URLエンコードで "%~" にエンコードされる文字でも、刈り取られ問題が発生しうる、ということである。 Tags:Internet Explorer 2009年 07月 25日
先の投稿のとおり、ライトニングトトーク用に5分間固定のカウントダウンタイマーを、Windows Mobile の Mobile Internet Explorer 用に HTML + JavaScript で作成したのだが、作成した当初はじゅうぶんに処理速度をチューニングできておらず、実用に耐えられなかった。
そこで急遽、Windows Mobile 機ではなく、ライトニングトークの PowerPoint プレゼンテーションを表示している PC デスクトップ上に、あわせてこのカウントダウンタイマーを表示することに作戦変更。 カウントダウンタイマーそのものは、Windows Mobile 用に作成した HTML + JavaScript 版をそのまま使うこととして、しかし、ライトニングトークのプレゼンの横に、Webブラウザを表示してカウントダウンタイマー動かすのもどうかと思う。 そこで、突貫工事で、System.Windows.Forms.WebBrowser コントロールだけで全面を占めている、小さなウィンドウサイズの WinForm アプリを書き上げた。 プロジェクト一式とビルド済みバイナリは SkyDrive に公開。 http://cid-5dd1e083875ff918.skydrive.live.com/self.aspx/%e5%85%ac%e9%96%8b/BrowserWidget.zip ライセンスを主張できるほどのコードではないので、ご利用・再利用・改変はどうとでもご自由にどうぞ。 コマンドライン引数に指定された URL を開くだけのシンプルな WinForm アプリである。 常に最前面表示 = On、透過度 = 50% にしてあるので、プレゼンの左上に重ねて表示してもいい具合である。 カウントダウンタイマー HTML をそのまま表示すると、さすがに大きすぎるので、HTML をちょっと書きかえて、CSS スタイル指定で zoom:0.5 とした。 本当は、タイトルバーに限らずウィンドウ内どこでもドラッグしてウィンドウ位置を変えられるようにし、タイトルバーは無しにしたかった。 WM_NCHITTEST に応えればいいのだろうと思いつつ、うまく実装・動作できなかったので、時間もなく早々に断念。 ツールスタイルのタイトルバーでお茶を濁すことに。 タイトルバー左の[X]ボタンも非表示にしたので、終了するにはキーボードで Alt + F4 を押すことになる。 これで 7月4日のライトニングトーク本番に臨んだ。 下の画像の左上、ご覧頂けるだろうか。 こんな風に表示されて、5分間の時を刻む次第。 ![]() Tags:ライトニングトーク 2009年 07月 07日
やたら長いタイトルではあるが、まぁ、タイトルのとおりの話題。
先日7/4(土)に CLR/H Windows 7 コミュニティ勉強会 with Tech Fielders に参加、そのライトニングトークにも登壇させて頂いた次第だが、そのときに使おうと思い、5分間のカウントダウンタイマーを HTML + JavaScript で作成した。 この HTML ページを手持ちの S11HT "EMONSTER" - Windows Mobile 6 - に搭載の Mobile IE で開いて、手元に S11HT を置いて計時しながらライトニングトークに臨もうとした次第。 それくらいのことは、別にどうという話ではないのだが、今回は、かるあさんのブログで知った CodeRun というサービスを使ったところがミソである。 (CodeRun のインパクトについては、上記、かるあさんのブログを参照されるのがよい。) さて、CodeRun に至った経緯は次のとおり。 先に書いたとおり、HTML + JavaScript で書いた動的ページを Windows Mobile で動作させたいわけだが、どうやら Mobile IE だと、セキュリティ上の都合であろうか、内蔵ストレージに保存した HTML を開いてもその中の JavaScript は実行してくれない模様。 ということで、HTML + JavaScript で作成されたカウントダウンタイマーを動作させるには、インターネット上のどこかでホストしてこれにアクセスする必要がある。 クライアント側の技術しか使ってないので、どれでも適当なホスティングサービスを借りて使うことでOKなのだが、そこで思い至ったのが CodeRun、というわけである。 CodeRun サービスを利用すれば、話題の "Webブラウザで動作する Visual Studio ライクな IDE" ももちろん魅力なのだが、加えて、Amazon のクラウドをベースとしたホスティングサービスを借りているのと同様なのだ。 件の CodeRun の Web ブラウザ上 IDE でちょこちょこと HTML & JavaScript ソースコードを編集し、そのまま "Deploy" ボタンをクリックすれば配置完了。 S11HT の IE 上でリロードすれば即動作確認できる。 "コードを編集" から "配置" までの簡便さは、当初考えていたよりあなどれない。 この快適さは意外とやみつきになりそう。 ということで、動作している画面キャプチャはこちら。 ![]() 下記 URL から開くことができる。 http://jsakamoto.s2.coderun.com/projects/LTCountDownTimer/index.html (分秒表示部分をクリックするたびに、計時開始 & 終了を繰り返す) 本当に、どうということはないつまらないソースだが、いちおう下記に公開しておく。 (そういう需要があるかどうかは知りませんが、用途問わずGIF画像の再利用やソース再利用・改変頂いて結構です。) http://cid-5dd1e083875ff918.skydrive.live.com/self.aspx/%e5%85%ac%e9%96%8b/LTCountDownTimer.zip 実は、結局のところ、このモバイル用に作ったカウントダウンタイマーは使わないで終わった。 理由の一つは、当初の作り方では、Windows Mobile 上で思ったような処理速度が得られなかったためである。 上記で公開しているのは、当時のコードからさらに処理速度をチューニングしたものである。 そのあたりの顛末は、また機会を改めて。 Tags:ライトニングトーク 2009年 07月 06日
先日7/4(土)、CLR/H Windows 7 コミュニティ勉強会 with Tech Fielders に参加してきた。
お約束というか、ライトニングトークにも登壇させて頂いた次第。 今回のライトニングトーク、PowerPoint のスライドではなくデジカメ画像を順繰り見せながらのトークもあれば、88枚以上(!)のスライドをどんどん切り替えながらのアップテンポなトークもあり、内容のみならず、その "見せ方" も大変楽しく勉強になった。 もちろん、肝心のセッションそのものも、"ウチはWeb屋だから Windows 7 なんてカンケーないぜ!" などとジョークはかましつつも、実際にはクライアント展開だとか、一部はデスクトップアプリケーションも作っているので、実は興味津々で勉強させて頂いた。 はるばる北海道までスピーカとしてきて頂いたエバンジェリストの方々、また、CLR/H スタッフ皆様のご尽力にお礼申し上げたい。 私のライトニングトークのスライドはこちら。 http://cid-5dd1e083875ff918.skydrive.live.com/self.aspx/%e3%83%a9%e3%82%a4%e3%83%88%e3%83%8b%e3%83%b3%e3%82%b0%20%e3%83%88%e3%83%bc%e3%82%af/Win7%20%e3%82%b3%e3%83%9f%e3%83%a5%e5%8b%89%e5%bc%b7%e4%bc%9a%20with%20Tech%20Fielders/2009-07-04%20LT%20UploadGB%20%7C5NO-SE%7C6.ppt ネタはこのブログで書いた「数GBのファイルをHTTPでPOSTできるか?」。 Tags:ライトニングトーク 2009年 06月 18日
実は自分は LINQ 大好きである。
LINQ の使えない C# なんてもう考えられない。 もともと Prolog や Haskell の体験もあり、また、SQL は好んでふんだんに使うし、jQuery のセレクタ万歳なので、宣言指向、How より What、集合操作は大好きである。 当然のごとく、LINQ to SQL や LINQ to Entity も多用する。 しかし、である。 小粒でアドホックなデータベースへの SELECT クエリを、ささっと書きたいときもある。 昔ながらに DataAdaptor などを使いながら DataSet や DataTable で結果を入手してもよいのだが、シンプルなオブジェクトにマップできたほうが、インテリセンス中毒である自分にとっては大変楽である。 となれば LINQ to SQL の出番なのだが、しかし、たかだかそれだけのために .dtml をプロジェクトに新規追加して、デザイナを開いて、サーバーエクスプローラからテーブルをドラッグ&ドロップして...というのは、なんだか馬鹿げているというか、大仰に過ぎると思う場面もある。 LINQ to DataSet という選択肢もある。 しかし、Fields<型>("カラム名") 拡張メソッドなどが用意されているものの、だからといって、特段、コードが堅牢になる・書きやすくなる・読みやすくなることはない感じがする。 もちろん、AsEnumerable() してからクエリ構文でいじったりなど、LINQ to DataSet を重宝しているケースも少なくないが、今回のテーマとはまた別の話。 で。 実は、LINQ to SQL を構成するクラス群のひとつであり、.dtml デザイナが吐くコンテキストクラスの基底クラス、System.Data.Linq.DataContext クラスをそのまま使えば、SELECT クエリに関しては簡単な O/R マッピングができてしまうのだ。 コード見たほうが理解は早い。 public class PersonType { public int PersonID { get; set; } public string PersonName { get; set; } } var connnection = new SqlConnection(...); var context = new DataContext(connection); var persons = context.ExecuteQuery<PersonType>( @"SELECT PersonID, PersonName FROM Persons WHERE PersonID BETWEEN @p0 AND @p1",12, 34); こんな感じで、Persons テーブルから PersonID が 12~34 であるレコードを取り出してきて PersonType 型のオブジェクトにマッピングし、IEnumerable<PersonType> で入手、ということができる。 SQL 文の SELECT 中の選択リストを、マッピング先クラスの同名のプロパティにマップしているわけだ。 ごくごく些細で局所的な SELECT クエリを行いたいときは、本当にこれは便利。
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||