C# Entity Framework Postgresをやりながら覚える

PostgresとC#でEntyty Frameworkを見ようみまねで使っています。

そろそろ、Entity Frameworkもちゃんと理解を進めていきたいと考えています。Entity Frameworkが理解できるようになると、データベースへの接続モデルが整理されプログラムのメンテナンスが容易になります。

私は勉強が苦手。複雑な事を論理的に理解して行っていくより、とりあえず動かしてみてその動きから理解を進めます。解説などは書けませんが、やった事、どういう動作になったかを少しずつ自分用の覚書にしながら後に蓄積していきたいと思います。

ところで、つまるところEntity Frameworkって何なの?という話です。

結論

DBへアクセスするためのフレームワークです。

ソース・コードのみでデータベースの設計まで行えるコード・ファースト。非常に快適なコード中心の開発ワークフローを可能にします。

ただ、私の環境ではすでにデータベースがあるので、コード・ファーストを試した感じにはなっていませんのでご了承ください。

まず手始めにやる事は、Postgres上でviewを作成します。このviewがEntityのモデルを作成するベースになります。データベースにアクセスして取得したいSQLをこのview上で実現しておきます。

言わずもがな、この時には何を抽出してアプリケーションに表示したいのか決まっていないといけません。

CREATE OR REPLACE VIEW tv_person AS 
SELECT cd,name,shozoku FROM t_person;
ALTER TABLE tv_person
  OWNER TO postgres;

クラスを追加して、Person Entityを作成します。このEntityではViewで作成するフィールドのプロパティを持っています。

public class Person
{
    public int cd { get; set; }
    public string Name { get; set; }
    public string Shozoku { get; set; }
}

DbContextにて、エンティティの管理を行います。このため、DbContextの派生クラスを作成、記述します。このクラスによって、データの保存などを行います。

Using System.Data.Entity;

public class MyContext: DbContext
{
   public DbSet<Person> Person { get; set; }
}

DbSetはエンティティ扱うことができます。登録/更新/削除といったエンティティで行うべき処理をDbSetクラスで把握することができます。

今日の収穫はモデルに利用するフィールドは、keyが2つある場合、ちゃんとkeyを2つ設定し、Orderをつけないと、値は取得できるものの同じ値が何回にもわたって出るだけで、思った通りの値が取得できないという事です。

Keyが2つある場合は複合キーの設定必須です。

記載はこのようにします。

public class CompositeKeyEntity
{
  // 複合キー1つ目
  [Key, Column(Order = 0)]
  public int Key1{get;set;}

  // 複合キー2つ目
  [Key, Column(Order = 1)]
  public string Key2 { get; set; }

  public string Data { get; set; }
}

キーが2つあるのに、1つしかキーを設定しないと、重複するレコードが大量に出力され思った通りの結果は得られません。

では、キーを設定しなければと思うと、エラーが発生します。

entyty.jpg

 

型 'System.Data.Entity.ModelConfiguration.ModelValidationException' のハンドルされていない例外が EntityFramework.dll で発生しました

追加情報:One or more validation errors were detected during model generation:

WpfApplication1.Entities.kyosys_support.JissekiTohaigo: : EntityType ' CompositeKeyEntity ' has no key defined. Define the key for this EntityType.

CompositeKeyEntity: EntityType: EntitySet ' CompositeKeyEntity ' is based on type ' CompositeKeyEntity ' that has no keys defined.

適切に複合キーの設定をする必要があります。

複合キーを設定する場合、2つのカラムに
[Key]
[Key]

とつけるのではだめです。

Primary Keyをはっきりさせる必要があり、Orderで区別します。
[Key, Column(Order = 0)]
[Key, Column(Order = 1)]

また、EntytyFrameworkと、コレクションは切っても切れない関係にあり、コレクションを多用する事になります。

このサイトが分かりやすいです。

テーブルデータをそのまま抽出する

        public static List<BasicTable> getList()
        {
            using (var context = new Context_schema01())
            {
                var li = context.BasicTable.Select(n => n);
                return li.ToList();
            }
        }
        public static List<ExtractionTable> getList(DateTime StartDate,DateTime EndDate)
        {
            using (var context = new Context_schema02())
            {
                var li = context.ExtractionTable.Where(n => n.dt01 >= StartDate & n.dt02 <= EndDate);
                return li.ToList();
            }
        }
        public static List<ExtractSortTable> getList()
        {
            using (var context = new Context_schema03())
            {
                var li = context.ExtractSortTable.Where(n => n.nen >= 20150).OrderBy(n => n.nen).ThenBy(n => n.furigana).ThenBy(n=>n.sex);
                return li.ToList();
            }
        }

 

IEnumerable
指定した型のコレクションに対する単純な反復処理をサポートする列挙子を公開します。

Object.GetType メソッド ()
現在のインスタンスの Type を取得します。

Type.GetGenericArguments メソッド ()
クローズ ジェネリック型の型引数またはジェネリック型定義の型パラメーターを表す Type オブジェクトの配列を返します。

System.Reflection.PropertyInfo
プロパティの属性を取得し、プロパティのメタデータにアクセスできるようにします。

Dictionary クラス
キーと値のコレクションを表します。

System.Collections
System.Collections 名前空間には、さまざまな標準、特殊、およびジェネリックなコレクション オブジェクトを定義する型が含まれます。

関連コンテンツ