問題のベース:
意図したしゃれ。
問題は、テキスト情報がDOS Cyrillic (CP-866)に直接エンコードされている非常に古い dBase データベースから始まります。これだけでは不十分なため、毎晩 MySQL データベースに転送され、そこにアクセスできます。 .
私は MySQL プロバイダーをインストールし、私の主なデータ アクセス方法である Entity Framework を使用してデータベースに接続しました。次に、実験的な理由で純粋な ADO.NET も使用しました。
CP-866と思われる値をデータベースからUTF-8に変換しようとするまで、すべてが予想よりもうまくいっていました。
var cp866 = Encoding.GetEncoding(866);
var utf8 = Encoding.UTF8;
string source = "some unreadable set of characters from the database";
byte[] cp866bytes = cp866.GetBytes(source);
byte[] utf8bytes = Encoding.Convert(cp866, utf8, cp866bytes);
string result = utf8.GetString(utf8bytes);
EntityFramework で 1 回、ADO.NET で 1 回読んだことがありますが、結果は同じです。
当時は不明でしたが、現在ではあまり知られていない理由により、機能しませんでした。エンコードと文字列値に関するいくつかの重要な記事を読んだ後、文字列変数自体の性質上、データベースの varchar フィールドに相当する文字列にそのような変換を適用することはできないと判断しました。
いくつかキーボードを叩いてから、ADO.NET MySQL Provider を使用し、テスト対象の列にCONVERT(varcharColumn, Binary)を追加してクエリをカスタマイズすることで、最終的にそれを実現しました。
それ以降、変換からの cp866 バイト配列が既にあるという唯一の違いを除いて、上記のコードを使用しました。私はもともと似たようなことをするつもりでしたが、MySQL プロバイダーは varchar フィールドからバイトを直接読み取ることができず、Entity Framework でそれを行う方法も見つけられませんでした。
はい、うまくいきますが、経験の浅い私でさえも正しく感じません。
質問:
1: Entity Framework が特定のフィールドを選択する方法を指定できますか?
私の最愛の ORM について、読み取り中に特定の varchar フィールドをバイナリに変換する必要があることを何とか説明したいと思います。
2: ADO.NET MySQL プロバイダーが varchar フィールドのバイトを最初に文字列としてプルせずに取得するようにする方法はありますか?
GetBytes メソッドは varchar と一緒に使用すると例外をスローし、通常は ADO.NET プロバイダーに存在する GetSqlBytes メソッドが MySQL バージョンにはありません。正しく読み取る必要があるすべてのフィールドに Binary Convert を書きたくありません。
3: おまけの質問: CP-866 でエンコードされた varchar フィールドを文字列として読み取ることは可能ですが、今度はエンコードを UTF-8 に適切に変更しますか?
今日の記事を読んだ後も、エンコーディングのトピックについて頭の中にまだ多くの混乱があります。欠けているものがあるかもしれないと今でも信じています。それは、次のような cp-866 でエンコードされた varchar フィールドから文字列を読み取ることが可能です。
string cp866EncodedValue = "Œ€„‹… Œ‹€„…Ž‚€ Šš…‚€"; //actual copy-pasted value
..次に、データベースのフィールドが CP-866 でエンコードされていることを念頭に置いて、UTF-8 に変換します。私が読んだことから、それが文字列になるとすぐに、それはユニコードであり、文字列は不変です。私はそれを配列表現で取得しようとし、それをcp866に変更してからutf8に変更しました.cp866自体をそのまま使用しようとしましたが、成功しませんでした.