はじめに
久々にはまったので、ここに記載を追記!!
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しようとすると、環境によってはキー名が異なることが原因で自動生成された操作が失敗してしまう。そのため、外部キー情報を取得してそれに対して操作することで問題の回避を図る。
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;
{
SqlFile(@"Migrations\DisableKey.sql");
}
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();
}
-- 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";
参考サイト
門外不出のOracle現場ワザ 第1章 目からウロコのOracleパフォーマンス分析テクニック
c# – EFによって生成されたクエリは実行に時間がかかりすぎる
C# Entity Framework 6 の DbContext で変更されたレコードと変更前後の値を取得する
※変更追跡の情報を取得する ChangeTracker の Entries メソッド
[C#]LINQ to Entitiesで発行されているSQL文を見たい
※ToTraceStringメソッド