[英]Entity Framework Core - mapping two joins to the same table
我有兩個表 Clients 和 Jobs。 一個客戶可以有多個工作。 但是,我在 Jobs 上還有第二個關系,它也應該指回稱為 WarrantyCompany 的客戶。 基本上,保修公司也是客戶。 好吧,客戶/工作關系是主要關系,但我想再次參考客戶表以獲取保修公司的詳細信息。
這是客戶表:
using JobsLedger.DATA.Entities.Interfaces;
using JobsLedger.DATA.Interfaces;
using System;
using System.Collections.Generic;
namespace JobsLedger.DATA.Entities
{
#nullable enable
public class Client : IEntityBase, IAuditedEntityBase
{
public Client()
{
Jobs = new List<Job>();
}
public int Id { get; set; }
// One warranty company client to a job.
public int? WarrantyCompanyId { get; set; }
public Job? WarrantyCompany { get; set; }
// One suburb to a client.
public int? SuburbId { get; set; }
public Suburb? Suburb { get; set; }
// If its a warranty company then we simply link it one to one to the brand id.
public Brand? Brand { get; set; }
public virtual ICollection<Job> Jobs { get; set; } = default!;
public virtual ICollection<Job> WarrantyCompanyJobs { get; set; } = default!;
}
#nullable disable
}
我正在使用以下方法引用作業表:
// One warranty company client to a job.
public int? WarrantyCompanyId { get; set; }
public Job? WarrantyCompany { get; set; }
工作表如下:
using JobsLedger.DATA.Entities.Interfaces;
using JobsLedger.DATA.Interfaces;
using System.Collections.Generic;
namespace JobsLedger.DATA.Entities
{
public class Job : IEntityBase, IAuditedEntityBase
{
#nullable enable
public Job()
{
Visits = new List<Visit>();
}
public int Id { get; set; }
public int? WarrantyCompanyId { get; set; }
public Client? WarrantyCompany { get; set; }
public int ClientId { get; set; } = default!;
public Client Client { get; set; } = default!;
}
#nullable disable
}
在此表中,我使用以下方法引用客戶端表:
public int? WarrantyCompanyId { get; set; }
public Client? WarrantyCompany { get; set; }
我正在使用 Entity Framework Core Fluent API 來創建關系。
我決定從客戶的角度來處理這兩種關系:
// Two one to many relationships between client and job.
modelBuilder.Entity<Client>()
.HasMany(t => t.Jobs)
.WithOne(g => g.Client)
.HasForeignKey(g => g.ClientId)
.OnDelete(DeleteBehavior.Restrict);
// Same table but a client can also be a warranty agent.
modelBuilder.Entity<Client>()
.HasMany(a => a.Jobs)
.WithOne(b => b.WarrantyCompany)
.HasForeignKey(b => b.WarrantyCompanyId);
我嘗試創建遷移,但是出現以下錯誤:
無法在“Client.Jobs”和“Job.WarrantyCompany”之間創建關系,因為“Client.Jobs”和“Job.Client”之間已經存在關系。 導航屬性只能參與單個關系。
這是不言而喻的。 我還嘗試從工作表的角度創建關系:
modelBuilder.Entity<Job>()
.HasOne(a => a.Client)
.WithOne(b => b.WarrantyCompany)
.HasForeignKey<Client>(b => b.WarrantyCompanyId);
我發現當有兩個返回到同一個客戶端表時,我無法將關系可視化。
從本質上講,簡而言之,我有一個客戶可以有一個到多個工作,但對於每個工作,我可能有一個可選的保修公司,其中保修公司是客戶。 客戶和工作之間的兩種關系。
如何在這兩個表之間具有主要關系和次要可選關系,以及二級保修公司關系是一對一還是一對多?
出現此問題是由於兩個關系被映射到 Client 類中的同一個 Jobs 集合。 由於實際上有兩個關系,它們不能重用相同的屬性。
您的客戶模型已經有第二個關系的集合。 您只需要修復映射。
// First client/job relationship
modelBuilder.Entity<Client>()
.HasMany(t => t.Jobs)
.WithOne(g => g.Client)
.HasForeignKey(g => g.ClientId)
.OnDelete(DeleteBehavior.Restrict);
// Second client/job relationship (warranty)
modelBuilder.Entity<Client>()
.HasMany(a => a.WarrantyCompanyJobs)
.WithOne(b => b.WarrantyCompany)
.HasForeignKey(b => b.WarrantyCompanyId);
為了便於閱讀,我簡化了表格屬性。
客戶表:
public class Client
{
public int Id { get; set; }
// One warranty company client to a job.
public int? WarrantyCompanyId { get; set; }
public Job? WarrantyCompany { get; set; }
public ICollection<Job> Jobs { get; set; } = default!;
public ICollection<Job> WarrantyCompanyJobs { get; set; } = default!;
}
和工作表:
public class Job
{
public int Id { get; set; }
public int? WarrantyCompanyId { get; set; }
public Client? WarrantyCompany { get; set; }
public int ClientId { get; set; } = default!;
public Client Client { get; set; } = default!;
}
對於配置,我創建了一個JobConfig
類
public class JobConfig : IEntityTypeConfiguration<Job>
{
public void Configure(EntityTypeBuilder<Job> builder)
{
builder.HasOne(s => s.Client)
.WithMany(g => g.Jobs)
.HasForeignKey(f => f.ClientId);
builder.HasOne(s => s.WarrantyCompany)
.WithMany(g => g.WarrantyCompanyJobs)
.HasForeignKey(f => f.WarrantyCompanyId);
}
}
在Context
類中,假設上下文類名稱是ProjectContext
,我覆蓋OnModelCreating
方法。
public class ProjectContext: DbContext
{
public ProjectContext()
{
}
public Client Client { get; set; }
public Job Job { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfiguration(new JobConfig());
}
}
它將生成一個表和這樣的關系。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.