Neutral Scent

App developments & Gadgets

ASP.NET 2.0 のSqlDataSourceでGuid

正直ASP.NETは、一見するとWindowsFormsにそっくりなわりに、細かい動きが全然違うし、Webの基本的なモデルをかなり逸脱してるので嫌いです。
まーそれはともかく、ASP.NET 2.0になって、IDEでぐりぐりやってると、SQLのデータを編集するWebページがわりと簡単にコードレスで出来るようになりました。
ですが、SQLのテーブルがPrimeryKey(主キー)にGuid(uniqueidentifier型)を使ってると、とたんに破綻して動かなくなるようです。
とりあえず、テーブルの表示はできますが、GridViewやDetailViewでInsertやUpdate/Deleteをやろう、などとするととたんにNG。

'/Page' アプリケーションでサーバー エラーが発生しました。
                                                                                                                                                              • -
sql_variant データ型から uniqueidentifier データ型への暗黙の変換は許可されません。CONVERT 関数を使用して、クエリを実行してください。 説明: 現在の Web 要求を実行中に、ハンドルされていない例外が発生しました。エラーに関する詳細および例外の発生場所については、スタック トレースを参照してください。 例外の詳細: System.Data.SqlClient.SqlException: sql_variant データ型から uniqueidentifier データ型への暗黙の変換は許可されません。CONVERT 関数を使用して、クエリを実行してください。

とかエラーを出して動きやしません。
で、なんじゃこりゃー? と思って、あーでもない、こーでもない、DataSetはどこだ? DataBindingで変換するのか? などと調べて回ったのですが、もーASP.NETわけわかりませんよ、ほんと。
まー、わけわからんのはともかく、結論としてはVSが生成するaspxの中のSqlDataSourceの定義がおかしい、ということのようです。

        
            
                
            
            
                
                
                
            
            
                
                
                
            
        

まーこんな感じで定義されてるわけですが、TabkeKeyがGuidのPrimeryKeyだとすると、Type=""がデフォルトでObjectです。ここんとこをStringに換えてやるだけで動くようになるようです。なんだかねぇ...。
VSのデザイナでSqlDataSourceのプロパティInsertQueryとかを編集すると、「コマンドおよびパラメーターのエディタ」とゆーのが開いてクエリの編集ができまして、ここでも詳細設定プロパティで一見Typeを変更できるように見えますが、これを変更してもaspxには反映されず元に戻ってしまいます。これバグですかね?
とにかく、こんな感じに変更するだけで動くようになります。

            
                
            
            
                
                
                
            
            
                
                
                
            

あー、全くASP.NETわけわかりませんよ...。
解決法のネタ元:
ASP.NET Forums - Guids are not very guid! Updating in DetailsView,FormView
http://forums.asp.net/thread/1210416.aspx

      • -

追記:
上記の方法でInsert文は動くのですが、Update文が動きません。
UpdateとDeleteでのGuidキーは、(編集しないのであれば)Type="Object"のままにしておくべきのようです。