0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Entity Framework - Code First Migration - Oracle ではまって勉強中...

Last updated at Posted at 2019-04-01

はじめに

久々にはまったので、ここに記載を追記!!

TODO

  • [ ]

ノウハウ

はまり④:自動採番動かない...

◆【Oracle】シーケンス(sequence)を使って自動発番する
 https://notepad-blog.com/content/147/
  ※ここと同じSequence/Triggerの自動採番方式で動かなくなる...
◆連番の自動採番方法
 https://ameblo.jp/archive-redo-blog/entry-10035189031.html
◆Entity Framework + Oracle で自動採番できるのか調べた
 https://minato128.hateblo.jp/entry/2013/03/06/001756

はまり③:エンティティの検証に失敗

◆EntityFramework SaveChange()時の例外発生時にSQLのエラーを表示させる
 https://qiita.com/yahweh/items/1f1f1bf8b09c7d60cfbd

◆[EntityFramework]SaveChanges() 時の検証
 http://itkaeru.blogspot.com/2013/03/entityframeworksavechanges.html

◆DbEntityValidationException-エラーの原因を簡単に特定するにはどうすればよいですか?
 https://www.javaer101.com/en/article/8669807.html

◆DbEntityValidationException - エラーの原因を簡単に判断する方法
 https://www.it-mure.jp.net/ja/c%23/dbentityvalidationexception-%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%AE%E5%8E%9F%E5%9B%A0%E3%82%92%E7%B0%A1%E5%8D%98%E3%81%AB%E5%88%A4%E6%96%AD%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/1072571349/

はまり②:複合キー追加

全テーブルに[Key]を追加したら大量のエラーが発生して困った...

参考サイト

◆リレーションシップ属性: InverseProperty と ForeignKey
 https://docs.microsoft.com/ja-jp/ef/ef6/modeling/code-first/data-annotations
◆リレーションシップ、ナビゲーション プロパティ、および外部キー
 https://docs.microsoft.com/ja-jp/ef/ef6/fundamentals/relationships

◆新しいデータベースの Code First
 https://docs.microsoft.com/ja-jp/ef/ef6/modeling/code-first/workflows/new-database
  ※EF でサポートされている注釈の完全な一覧は次のとおりです。
   KeyAttribute
   Stringlength 属性
   MaxLengthAttribute
   ConcurrencyCheckAttribute
   RequiredAttribute
   タイムスタンプ属性
   ComplexTypeAttribute
   ColumnAttribute
   TableAttribute
   InversePropertyAttribute
   ForeignKeyAttribute
   DatabaseGeneratedAttribute
   NotMappedAttribute

◆Entity Framework 1対1
 https://memo-c-sharp.blogspot.com/2017/02/entity-framework-11.html
◆エンティティフレームワークの1対1の関係で、連合の主な終わりは何を意味しますか?c#、エンティティフレームワーク、データベース設計、外部キー関係
 https://living-sun.com/ja/c/148523-what-does-principal-end-of-an-association-means-in-11-relationship-in-entity-framework-c-entity-framework-database-design-foreign-key-relationship.html
  ※1対1では[Required]を付与する必要がある!!

◆EntityFramework Core 3.1 を使って、色々な一対多のリレーションを試してみた
 https://thinkami.hatenablog.com/entry/2019/12/18/230557
  ※InversePropertyって何だ!?って時に
  ※後でデータアノテーションは後で一通りチェックしないと...

◆c# - 2つのエンティティ間の複数の関係を定義する方法は?
 https://cloud6.net/so/c%23/1718918
  ※下記エラーメッセージの対応パターン
   「System.InvalidOperationException: 'タイプ' User 'のナビゲーションプロパティ' Photo.Owner 'で表される関係を特定できません。関係を手動で構成するか、「[NotMapped]」属性を使用するか、「OnModelCreating」の「EntityTypeBuilder.Ignore」を使用して、このプロパティを無視します。」

◆Entity Framework Core におけるリレーションシップについて
 http://kuttsun.blogspot.com/2018/01/entity-framework-core_11.html
◆Shadow および Indexer プロパティ
 https://docs.microsoft.com/ja-jp/ef/core/modeling/shadow-properties
  ★この
 

はまり①:外部キー制約の有効/無効化

Oracleはキー名称が30(!?)を超えると数字の文字列に置換される(⇒FK_WakaOnsiteCourse_1391782694)
これをMigrationしようとすると、環境によってはキー名が異なることが原因で自動生成された操作が失敗してしまう。そのため、外部キー情報を取得してそれに対して操作することで問題の回避を図る。

DisableDey.sql
BEGIN
  FOR row IN (SELECT B.TABLE_NAME, B.CONSTRAINT_NAME
               FROM DBA_CONSTRAINTS A,DBA_CONSTRAINTS B
               WHERE A.CONSTRAINT_NAME = B.R_CONSTRAINT_NAME
                 AND A.CONSTRAINT_TYPE = 'P'
                 AND B.CONSTRAINT_TYPE = 'R'
                 AND A.TABLE_NAME = 'TableName'
                 AND B.OWNER = 'SchemaName')
  LOOP
    EXECUTE IMMEDIATE 'ALTER TABLE ' || '""SchemaName"".""' || row.TABLE_NAME || '""' ||
                      ' DISABLE CONSTRAINT ""' || row.CONSTRAINT_NAME || '""';
  END LOOP;
END;
202200000000000_Migration.cs
        {
            SqlFile(@"Migrations\DisableKey.sql");
        }
Configuration.cs
        protected override void Seed(OracleDBContext context)
        {
            context.Database.ExecuteSqlCommand(AlterForeignKeyStatus("Departments"));
        }

        private String AlterForeignKeyStatus(String tableName)
        {
            var sqlCommand = new StringBuilder();
            sqlCommand.AppendLine(@"BEGIN");
            sqlCommand.AppendLine(@"  FOR row IN (SELECT B.TABLE_NAME, B.CONSTRAINT_NAME");
            sqlCommand.AppendLine(@"               FROM DBA_CONSTRAINTS A,DBA_CONSTRAINTS B");
            sqlCommand.AppendLine(@"               WHERE A.CONSTRAINT_NAME = B.R_CONSTRAINT_NAME");
            sqlCommand.AppendLine(@"                 AND A.CONSTRAINT_TYPE = 'P'");
            sqlCommand.AppendLine(@"                 AND B.CONSTRAINT_TYPE = 'R'");
            sqlCommand.AppendLine(@"                 AND A.TABLE_NAME = '" + tableName + @"'");
            sqlCommand.AppendLine(@"                 AND B.OWNER = 'SchemaName')");
            sqlCommand.AppendLine(@"  LOOP");
            sqlCommand.AppendLine(@"    EXECUTE IMMEDIATE 'ALTER TABLE ' || '""SchemaName"".""' || row.TABLE_NAME || '""' ||");
            sqlCommand.AppendLine(@"                      ' ENABLE CONSTRAINT ""' || row.CONSTRAINT_NAME || '""';");
            sqlCommand.AppendLine(@"  END LOOP;");
            sqlCommand.AppendLine(@"END;");
            return sqlCommand.ToString();
        }
tool.sql
-- PrimaryKey情報取得
SELECT A.CONSTRAINT_NAME, A.STATUS
  FROM DBA_CONSTRAINTS A
  WHERE A.CONSTRAINT_TYPE = 'P'
    AND A.TABLE_NAME = 'TableName'
    AND A.OWNER = 'SchemaName'
;

-- ForeignKey制約情報取得
-- SELECT B.OWNER || '/' || B.TABLE_NAME || '/' || B.CONSTRAINT_NAME || '/' || B.STATUS
SELECT B.CONSTRAINT_NAME, B.STATUS
  FROM DBA_CONSTRAINTS A,DBA_CONSTRAINTS B
  WHERE A.CONSTRAINT_NAME = B.R_CONSTRAINT_NAME
    AND A.CONSTRAINT_TYPE = 'P'
    AND B.CONSTRAINT_TYPE = 'R'
    AND A.TABLE_NAME = 'TableName'
    AND B.OWNER = 'SchemaName'
;

-- 結果表示(デバッグ用)
SET SERVEROUTPUT ON

-- 外部キー無効化
alter table "SchemaName"."WakaOnsiteCourses" disable constraint "FK_WakaOnsiteCourse_1391782694";
alter table "SchemaName"."OnlineCourses" disable constraint "FK_OnlineCourses_DepartmentID";
-- 外部キー有効化
alter table "SchemaName"."WakaOnsiteCourses" enable constraint "FK_WakaOnsiteCourse_1391782694";
alter table "SchemaName"."OnlineCourses" enable constraint "FK_OnlineCourses_DepartmentID";

参考サイト

:link: 門外不出のOracle現場ワザ 第1章 目からウロコのOracleパフォーマンス分析テクニック

:link: c# – EFによって生成されたクエリは実行に時間がかかりすぎる

:link: C# Entity Framework 6 の DbContext で変更されたレコードと変更前後の値を取得する
 ※変更追跡の情報を取得する ChangeTracker の Entries メソッド

:link: [C#]LINQ to Entitiesで発行されているSQL文を見たい
 ※ToTraceStringメソッド

:link: EntityFramework(18):トランザクション処理

:link: 4. データの挿入、読み出し、更新、削除
 
:link: Code First Migrationでぐだぐだになる

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?