Modelでのリレーションについて

Coreではない、ASP.NET MVCの時には問題のなかったのにCoreに変更してうまくいかなくなり対応したはずだが、諸事情によりソースがぶっ飛んで復活できなくなり困ったのだが、改めて対応したのでメモしておく。

①そもそもテーブルの設計がイマイチ
権限設定テーブルで以下のようなテーブル
 　CREATE TABLE [dbo].[authorities](
    	[authority] [int] NOT NULL,
    	[remarks] [nvarchar](50) NOT NULL,
    	[delete_flag] [bit] NOT NULL,
    	[create_date] [datetime2](7) NULL,
    	[create_host_name] [nvarchar](128) NULL,
    	[modify_date] [datetime2](7) NULL,
    	[modify_host_name] [nvarchar](128) NULL,
    	[timestamp] [timestamp] NULL,
    ...
テーブル名がエンティティにした際、Authorityとなり、その中でキーとなる項目が
authorityでプロパティは自動でAuthorityとなる。
本来であればid とするところ、設計が古いのでこのような設定となっている。
実際にエンティティを作成した際には
    [Column("authority")]
    [DisplayName("権限")]
    public int Id { get; set; }
上記のように設定してある。

②リレーションする従業員テーブル
CREATE TABLE [dbo].[employees](
	[id] [int] IDENTITY(1,1) NOT NULL,
	[code] [nchar](2) NOT NULL,
	[name] [nvarchar](20) NOT NULL,
	[password] [nvarchar](10) NOT NULL,
	[authority] [int] NOT NULL,
	[branch_id] [int] NOT NULL,
テーブル上ではauthority同時でjoinしていた。本来であれば、その下の
branch_idのようにauthority_idとすべき、
実際にエンティティにした際は以下のようにした。

public partial class Employee
{
    [Column("id")]
    [DisplayName("ID")]
    public int Id { get; set; }

    // 未使用
    public string Code { get; set; }

    [Required(ErrorMessage = "{0}は必須入力です。")]
    [StringLength(4, MinimumLength = 4, ErrorMessage = "{0}は4文字でお願いします。")]
    [Column("code2")]
    [DisplayName("社員コード")]
    public string? Code2 { get; set; } = null!;

    [Required(ErrorMessage = "{0}は必須入力です。")]
    [StringLength(20, ErrorMessage = "{0}は20文字以内でお願いします。")]
    [Column("name")]
    [DisplayName("名前")]
    public string Name { get; set; } = null!;

    [Required(ErrorMessage = "{0}は必須入力です。")]
    [StringLength(10, ErrorMessage = "{0}は10文字以内でお願いします。")]
    [PasswordPropertyText]
    [Column("password")]
    [DisplayName("パスワード")]
    public string? Password { get; set; }

    [Required(ErrorMessage = "{0}は必須入力です。")]
    [Column("authority")]
    [DisplayName("権限")]
    public int AuthorityId { get; set; }

    [Required(ErrorMessage = "{0}は必須入力です。")]
    [Column("branch_id")]
    [DisplayName("所属営業所")]
    public int BranchId { get; set; }
    ...
    public virtual Authority Authority { get; set; }

    public virtual Branch Branch { get; set; }

③このままだと、スキャフォールディングした際にエラーになる。
    
    選択したコード ジェネレーターを実行中にエラーが発生しました！
 'The 'Authority' property 'Employee.Authority' could not be mapped
 because the database provider does not support this type. Consider converting the property value to 
 a type supported by the database using a value converter.
 See https://aka.ms/efcore-docs-value-converters for more information.
 Alternately, exclude the property from the model using the '[NotMapped]' attribute or by using 
 'Entity TypeBuilder.Ignore' in 'OnModelCreating'.'

④ソースが飛んだので以前にどういう対応をしたのか覚えてないのだが。。
copilotの力を借りて修正したのが以下（コンテキストを修正）

protected override void OnModelCreating(ModelBuilder modelBuilder)
{

…

modelBuilder.Entity<Employee>(entity =>
{
    entity.HasKey(e => e.Id).HasName("PK_tblStaff");

    …

// Authority エンティティとの関係を設定
entity.HasOne(e => e.Authority)
 .WithMany(a => a.Employees)
 .HasForeignKey(e => e.AuthorityId)
 .OnDelete(DeleteBehavior.ClientSetNull)
 .HasConstraintName("FK_Employee_Authority");

 });

 今ここ。とりあえず、スキャフォールディングはできるようになった。
 あと、注意としてAIに任せてたから気づかなかったけど、元々、
 modelBuilder.Entity<Employee>には、以下が当然、存在しているのに、
 
 entity.Property(e => e.Authority).HasColumnName("authority");

 上記の修正を「追加」でmodelBuilder.Entity<Employee>の最後に追加したので、
 スキャフォールディングが以下のエラーで通らなかった。。
  The property or navigation Authority could not be added to the Employee
 type because a property or navigation with the same name already exists on the Employee type.

 このエラーのやり取りを繰り返してcopilotにAuthority エンティティとの関係を設定の修正ソースを教えてもらったので、あくまで、
 entity.Property(e => e.Authority).HasColumnName("authority");を
 修正することになる。
 ※要はentity.Property(e => e.Authority).HasColumnName("authority");を消して、// Authority エンティティとの関係を設定　以下のソースを追加する。