中央競馬の予想や購入したもののメモなどを書いて行こうかと。まあ、個人的なメモ的なブログです。
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
諦めがつかず、別のラッパーのテストもしてみたり^^; 現状に不満が残るまま開発進めるのは少し気が引けるので、以前にも目にしていたSQLite.CodeFirstを試してみる。が、思う様に動いてはくれなかった。自分の理解不足なのかもだが、SQL Server ExpressをVS2019でコードファーストから利用すると別にミグレーションとかしなくても、普通にデータベースが出来てテーブルも作成される感じで滅茶苦茶気に入っていたので、そんな感覚でSQLiteも利用したいってのが心のどこかに引っ掛かりを残してる理由かも。まあ、SQLite.CodeFirstのグーグル先生が見つけてくれた記事では簡単にって事の様でしたが自分には無理。
で、諦めムードで元のSystem.Data.SQLite.Coreでデバッグ。ああ、流石にここまででほぼ必要なソースのコンバートは終わってる感じです。まあ、若干お手軽なコンテキストのAdd()なんか使うコーディングは使わないかもなのでコンバートしてません。
今はテーブルに1,723個の項目があるInsertで"unknown error Insufficient parameters supplied to the command"と言われ、途方に暮れながら何が悪いのか確認中です。Visual Studioでのデバッグは色々と楽に出来る感じなのに、これってどのパラメータでエラーになっているか手作業で確認するしかないのかな? まあ、単に自分が使い方理解してないのかもですが、大変です。
これとは別に今回のコンバート作業から起きた問題がVBでは単にVal()関数でお手軽に文字列から数値に変換してたのが、まあ、C言語由来なのか型にうるさいC#なので、数値といっても型が何かとかで分けたり^^; で、提供元からのデータが"0000"として、これが"#0.0"のデータたとしてVBでは
Val(strIn)/10
ってな感じだったかな。単純なコンバートでは
float.Parse(strIn)/10.0F
になるとは思ったんですが、デバッグしてる時にテーブル覗いてみて本来1.2であるはずのデータが1.199999989みたいな。その昔まだNECで汎用機のFORTRANコンパイラ担当だった頃、東北大学の学生が0.1を10回足しても1にならず、0.9999989的な結果なのはおかしくない?って質問があり、パッチ出してた記憶があるけど、バイナリな世界を理解してると別に不思議な話ではなく、2進数で10進数の0.1が正確に表現しきれない、つまり近似値が使われるんですが、この近似値の誤差が結果に表れるのが原因なんですが、これをふと思い出し、割り算せずに直にデータが変換される様に
float.Pars(Strings.Left(strIn,3) + "." + Strings.Right(strIn,1))
としてみたんです。結論から言えば、どこでどんな処理が内部的に行われているかまでは把握してないし、そもそもMS社が悪いのか、ラッパーの方でなにかしてるのかまでは判断出来ません。MS社の前科から疑うのもどうかとは思うけど、いや、学生時代、NEC PC-8001搭載のN-BASICで宿題してて、大学の端末からやった様に見せかけてプログラム書いて提出したら、見た目のプログラムは間違ってないのに、結果がなんでこんな数字になっているか理解出来ないと教授に言われ、却下されたw これ、単にビル君のお粗末なBASIC精度が原因だったんですけど。ま、それから宿題は当時のTurbo Pascalでやる様になりました。$29.98とかで購入して爆速なコンパイルで精度問題も回避出来ました。MS-DOS以前のCP/M時代の話ですけどね。
で、話それましたが元に戻すと、このコーディングしても誤差は出ました。どこがなんで出しているのか不明なままorz で、これ、提供元のデータが" "だとVBでは問題ないけどってか、数値化後の割り算なら問題ないけど、フォーマット的に小数点打つと" . "的な文字列になりエラーなるんですよ。提供元の初期値的なミスはクレーム上げたいけど、直ぐに対処されるか不明なので自己防衛としてif分で回避するコーディングを全てに行う事に。これが相当な作業なのでまた遅れが出ます。
やれやれ、Microsoft.Data.SqliteでなぜSystem.Data.SQLiteと同じにコーディングしてもエラーになるのかは調べる気にもならず、別のラッパー探ししてると、現状のお勧め的なものとしてSystem.Data.SQLite.Coreを発見! これ、どうやら正当なSystem.Data.SQLiteの継承者っぽいです。なんでここまで探すのに苦労してるんだろって不思議な位ですが、現在のプロジェクトにインストールした全てのラッパーを削除。NuGet ソルューションのインストール済みを空にしてまずはSystem.Data.SQLite.Coreを導入。まあね、次は本来必要のない作業だったのですが、SqliteConnectionとかにしてしまったソースを元のSQLiteConnectionに戻す。しかし、まあ、当たり前ですが、コンテキスト宣言がエラーのまま。System.Data.SQLiteの時にも確かEntityFrameworkを入れてました。これ、自分で入れた記憶がないので、System.Data.SQLiteインストール時に依存関係でインストールされたんだと思います。で、こいつは.NET6未対応だった筈で、今回のにはやはりMicrosoft.EntityFrameworkCore.Sqliteを入れる。で、これでこのまま行ければと思いましたが、やはりミグレーションが必要になるのでMicrosoft.EntityFrameworkCore.Toolsも入れ、一応、前の環境で生成してたMigrationフォルダとDBファイルは削除して、新たにAdd-MigrationとUpdate-Databaseすると普通にDBファイルは生成されました。ちと気になりDB Browser for SQLite使って中覗いでみると、う~ん、System.Data.SQLiteの時にはSQLiteらいからぬ、byte型宣言された項目はtinyintとかDateTime型がdatetimeとなる等、逆に素直に見れたのですが、今回の環境では、Microsoft.Data.Sqlite環境と同じく、SQLiteがサポートする4つの型にされてました。
これが今後データ蓄積した時にDBファイルの容量に影響するのかどうかは今となってはわざわざ調べる事はないですが、気になる所です。
で、まあ、データ登録の簡単なパーツのコンバートも終えていて、Microsoft.Data.Sqliteでエラーとなっていたものが普通にSystem.Data.SQLiteの時の様に動作してくれました。これで無事にVisual Studio Community 2022のC#での開発に戻れます。
余談ですが、このVisual Studio Commnunity 2022はうちでは未だPreview Ver.17.1.0 Preview 1.1って事ですが、確か.NET 6とC# 10になると思ってたんですが、試しにC#の新機能のnamespace1つだけなら中カッコ{}無が行ける筈と試すがNGでした。何だろ、正式版のVSC2022からかは不明です。
以前コンバータがtryに未対応的な事を書きましたが、どうやらたまたまコンバートしようとしたソースでうまくtryが処理出来なかっただけで、未対応という事ではないようです。データベースへの登録処理まわりのソースをコンバートしてみたら普通に出来ました。まあ、ただ、Systerm.Data.SQLiteとMicrosoft.Data.Sqliteの違いやら、諸々で苦労してます。まあね、名前見ただけでQとLが小文字になってたりする訳でSQLiteParameterがSqliteParameterだったりして、その修正が必要だったりします。
それ以外にはEncodingでも問題がありました。VBでは普通に使えていたのに
return Encoding.GetEncoding("Shift_JIS").GetBytes(myString);
とエンコードするにはその前に
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
しないとエラーになったりしました。グーグル先生にお願いして解決してます。
コンバータ使っているので基本的なコネクト・トランザクション・パラメータ設定からのクエリ実行な処理手順が同じなのにエラーになる。後は言語の性質の違いからコーディング変更も必要だったり、先行き不安です。
System.Data.SQLiteが.NET6対応になれば、戻す事で少し楽に作業が進められるかもですが、このあたりの予定は不明なので、既に対応済みな別のラッパー探す必要もあるかもしれませんorz
本業休業中なので一気に作業進めてみました。コンバータは前者はEdgeでは動かないけどchromeかFirefoxならって、この為だけにchrome入れたけど、結局どうすれば機能するのか不明なままでした。後者を利用してコンバート作業したんですが、VBの配列をC#にした時に添字が()のままなので、手動で[]にするのが苦労した所かな。日本語は全く問題にならなかった。
で、実際のコーディング部分はまだこれからなんですが、どうもコンバータはTryに対応してない感じで、Try多用してるので、手動な作業を覚悟してます。
ああ、VBに慣れ過ぎでC#はやはり相当苦労しそうです。フォームイベントに何か書きたい時にVBでは直ぐにエディタから選んで書けたのに、C#ではフォームのイベントでもコントロールのイベントでも、デザイン画面で対象をフォーカスした状態でプロパティウィンドウをイベントに切り替えて指定する必要がある。初めはこんな名前だろうってコードの方に直接追記して実行しても一向に呼ばれないので半日は時間の浪費orz
System.Data.SQLiteでは
Public Overridable Property メンバーT() As DbSet(Of メンバー)
って感じにテーブル定義してても、SQLite内のテーブルは「メンバー」で出来てたんですが、Microsoft.EntityFrameworkCore.Toolsでは「メンバーT」となる。これは微妙に見た目が気になるのでちと検討してみます。
public virtual DbSet<メンバー> メンバー { get; set; }
とするか、
[Table("メンバー")]
public class メンバー
{
又は、
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<メンバー>().ToTable("メンバー");
とするか悩む所です。
マイクロソフトが全面的にVisual Basicを捨てて、C#に移行しているのはドキュメント読んだりして分かってはいたものの、年齢的にも時間の制約からも避けてきました。しかし、まだ数年以上は生涯の趣味として続けると思うので、自分自身が移行する、決断する最後のチャンスと思うので^^; BASICで初めてプログラム書いたの1979年なんで42年前かな。その後、FORTRAN、Pascal、PL/I等大学でやりましたが、社会人になりHPLだったかなNEC固有の言語だったかもだけど。世間的にUnixなんかも広がりCも独学で習得して大分プロとして使いました。プロ辞める数年前からVisual Basicも使い始め、バブル崩壊でシステムエンジニアを引退。以後は趣味としてVisual Basic使い続けてきました。さようなら、Visual Basic。
とはいうものの、ここまで書き上げたソースは数メガレベルだと思うので、これをC#にする作業だけでも半端ない時間が掛かるのは当然で何とか短い時間で進めたい。どうやら、コンバーターもあるっぽいので最大限に利用していこうとは思います。
Convert VB.NET to C# - A free code conversion tool - developer Fusion
Code Converter C# to VB and VB to C# – Telerik
まあ、問題は多く使われてる日本語が通るのかかな^^;