0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

Posted at

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

①そもそもテーブルの設計がイマイチ
権限設定テーブルで以下のようなテーブル
 CREATE TABLE [dbo].[authorities](
[authority] [int] NOT NULL,
[remarks] nvarchar NOT NULL,
[delete_flag] [bit] NOT NULL,
[create_date] datetime2 NULL,
[create_host_name] nvarchar NULL,
[modify_date] datetime2 NULL,
[modify_host_name] nvarchar 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 NOT NULL,
[name] nvarchar NOT NULL,
[password] nvarchar 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(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には、以下が当然、存在しているのに、

entity.Property(e => e.Authority).HasColumnName("authority");

上記の修正を「追加」でmodelBuilder.Entityの最後に追加したので、
スキャフォールディングが以下のエラーで通らなかった。。
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 エンティティとの関係を設定 以下のソースを追加する。

0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?