情報科学屋さんを目指す人のメモ(FC2ブログ版)

何かのやり方や、問題の解決方法をどんどんメモするブログ。そんな大学院生の活動「キャッシュ」に誰かがヒットしてくれることを祈って。

ブログ内検索

スポンサーサイト このエントリーを含むはてなブックマーク

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
スポンサー広告 | 編集

DataReaderオブジェクトに、結果の行数を表すプロパティがない理由 このエントリーを含むはてなブックマーク

System.Data.SQLiteを利用していて、"SELECT DISTINCT"を利用して、格納されている値にどのようなものがあるのかを調べようと思いました。

using (SQLiteConnection cnn = new SQLiteConnection("Data Source=data.db"))
using (SQLiteCommand cmd = cnn.CreateCommand())
{
    cnn.Open();

    cmd.CommandText =
        "SELECT DISTINCT ATTRIBUTE_NAME FROM TABLE_NAME";

    using (SQLiteDataReader reader = cmd.ExedcuteReader())
    {
        result = new string[###  謎  ###];
        int i = 0;
        while (reader.Read())
        {
            result[i] = reader[0];
            i++;
        }
    }
}

return result;

コードは以上のようになります。data.dbというSQLiteデータベースファイルのTABLE_NAMEテーブルのATTRIBUTE_NAME属性に含まれている値の一覧を、重複を除いて取得しようとしています。一覧は、SQLiteDataReader型の、readerオブジェクトから得られます。

ここで、結果を配列に格納したいので、まず配列のサイズを決定する必要が出てきます。

すると、readerオブジェクトのLengthプロパティがあるのだろうと思ったりしますが、Lengthはおろか、行数を表すプロパティは一切ありません。つまり、配列のサイズを決定することができないのです。

このことについて調べていると、「Visual C# で OleDbDataReader クラスまたは SqlDataReader クラスを使用するときに、フェッチされるレコード数を示す RecordCount プロパティが存在しない 」というページを発見し、結果の行数をreaderオブジェクトから取得することはできないということが分かりました。

そのページには、SELECT COUNT(*)を利用するようにと記述されています。そこで、その通りに、上記のプログラムを書き直すと、以下のようになります。

using (SQLiteConnection cnn = new SQLiteConnection("Data Source=data.db"))
using (SQLiteCommand cmd = cnn.CreateCommand())
{
    cnn.Open();

    cmd.CommandText =
        "SELECT COUNT(*)" +
        "FROM (" +
        "SELECT DISTINCT ATTRIBUTE_NAME FROM TABLE_NAME" +
        ")";

    int resultCount = int.Parse(cmd.ExecuteScalar().ToString()); 

    cmd.CommandText =
        "SELECT DISTINCT ATTRIBUTE_NAME FROM TABLE_NAME";

    using (SQLiteDataReader reader = cmd.ExedcuteReader())
    {
        result = new string[resultCount];
        int i = 0;
        while (reader.Read())
        {
            result[i] = reader[0];
            i++;
        }
    }
}

return result;

ちなみに、DataReaderの、FieldCountは、行数ではなく、結果の列数を表すプロパティです。今回の例では、必ず1になっているはずです。

スポンサーサイト
データベース | コメント:0 | トラックバック:0 | 編集

System.Data.SQLiteをLINQ to SQLで利用しよう(失敗編) このエントリーを含むはてなブックマーク

今回は、失敗の記録です。失敗の記録も、失敗としてここにメモしておきます。

やりたかったのは、System.Data.SQLiteで扱っているデータベースを、LINQを使って扱えるようにすることです。 以下、今回行って手順を、失敗するまで紹介します。

1.データベース作成

とりあえず、LINQを使わず、地道にC#からSQLを実行するなりして、SQLiteデータベースファイルを作成する。

2.サーバエクスプローラにデータベースを追加

サーバエクスプローラのデータ接続を右クリックして、接続の追加(A)..から、手順1で作成したデータベースファイルを追加する。

3..LINQ to SQLクラスの追加

ソリューションエクスプローラ上で、プロジェクトを右クリックして、「追加(D)>新しい項目(W)」から、「LINQ to SQL クラス」を追加します。すると、*.dbmlファイルが作成されます。.dbmlファイルを元に、LINQ to SQLで利用するクラス群が生成されます

4.GUIで.dbmlファイルを自動作成する

「オブジェクト リレーショナル デザイナを使用すると、コードのデータ クラスをグラフィックスで表示できます。 データ クラスを作成するには、項目を サーバ エクスプローラ または ツールボックス からこのデザインサーフェイスにドラッグします。」と表示されているところへ、手順2で追加したデータベースのTablesの中から、LINQ to SQLで接続したいテーブルをドラッグアンドドロップします。

5.エラーメッセージ→失敗

「選択されたオブジェクトにはサポート外のデータ プロバイダが使用されています。」と表示されてしまいました。失敗です。

失敗してしまったわけですが

LINQ to SQLを利用したかったのですが、残念ながら失敗してしまいました。LINQと同様の機能を持つ、ADO.NET Entity Frameworkを本当は利用したいのですが、情報が少なく、なかなか利用する気になれません。ということで、とりあえずあきらめ、現状で我慢します。

.NET開発テクノロジ入門~.NETの基礎からクラウドテクノロジ Windows Azureまで
プログラミングMicrosoft ADO.NET2.0
プログラミングMicrosoft ASP.NET 3.5

データベース | コメント:0 | トラックバック:0 | 編集

C#でローカルのデータベースを利用したい このエントリーを含むはてなブックマーク

C#/.NETから、Webを利用するのでも、サーバを立てるのでもない、デスクトップアプリケーション用のローカルデータベースを利用したいと思った。

そこで、候補は2つ。

  • SQL Server Compact 3.5
    Microsoft純正だけど、とにかく新しく、人気がない。情報も少ない。
  • System.Data.SQLite
    SQLite自体はとてもローカルデータベースとして人気だし、純正じゃないけど、機能はしっかりしているみたい。公式の情報はmsdnに比べれば少なめかもしれないが、SQLiteブランドは強い。

ということで、System.Data.SQLiteを採用することに。

なんとなく、各サイトを見ていると、ADO.NET 2.0という数字が気になり、.NET Framework 2.0で作っているところを見かけたりで、不安でしたが、とりあえず、サンプルのようなコードを、自分で作った.NET Framework 3.5のプロジェクト上でも動かすことはできました。だから、気にせず使えるのかなぁと思っておきます。

SQLのことは全然詳しくないけれど、データベース自体はおもしろそうだし、作れるアプリケーションの幅が広がるので、ちょっとがんばってみようかと思います。

.NET | コメント:0 | トラックバック:0 | 編集
 | HOME | 
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。