當子表的多個外鍵關連同一主表時,EF Core模型應該如何配置呢?
例:記錄一條銷售單信息,需要保存銷售員、和制單人(記錄的操作人),而這兩個字段都需要指向User表。
銷售單表(子表)B01_SO模型類如下:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.ComponentModel.DataAnnotations; namespace Test.Models { public class B01_SO { [Key] public int ID { get; set; } [Display(Name ="銷售單號")] [StringLength(50)] [Required] public string SONum { get; set; } [Display(Name = "單據編號")] [StringLength(50)] public string TKNum { get; set; } [Display(Name = "交期")] [Required] public DateTime Dtime { get; set; } [Display(Name = "產品描述")] [StringLength(200)] [Required] public string Description { get; set; } [Display(Name = "銷售員")] public int? SaleID { get; set; } [Display(Name = "銷售員")] public User Sales { get; set; } [Display(Name = "制單人")] public int? UserID { get; set; } [Display(Name = "制單人")] public User User { get; set; } } }
User表(主表)模型類如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace Test.Models { public class User { [Key] public int ID { get; set; } [Display(Name = "用戶名")] [StringLength(50)] [Required] public string Name { get; set; } [Display(Name = "郵箱")] [StringLength(100)] [Required] public string Email { get; set; } [Display(Name = "密碼")] [StringLength(50)] [Required] public string Password { get; set; } [Display(Name = "是否啟用")] [Required] public bool Enabled { get; set; } [Display(Name = "性別")] [StringLength(10)] [Required] public string Gender { get; set; } [Display(Name = "中文名")] [StringLength(100)] public string ChineseName { get; set; } [Display(Name = "英文名")] [StringLength(100)] public string EnglishName { get; set; } [Display(Name = "照片")] [StringLength(200)] public string Photo { get; set; } [Display(Name = "QQ")] [StringLength(50)] public string QQ { get; set; } [Display(Name = "公司郵箱")] [StringLength(100)] public string CompanyEmail { get; set; } [Display(Name = "工作電話")] [StringLength(50)] public string OfficePhone { get; set; } [Display(Name = "分機號")] [StringLength(50)] public string OfficePhoneExt { get; set; } [Display(Name = "家庭電話")] [StringLength(50)] public string HomePhone { get; set; } [Display(Name = "手機號")] [StringLength(50)] public string CellPhone { get; set; } [Display(Name = "地址")] [StringLength(500)] public string Address { get; set; } [Display(Name = "備注")] [StringLength(500)] public string Remark { get; set; } [Display(Name = "身份證")] [StringLength(50)] public string IdentityCard { get; set; } [Display(Name = "生日")] public DateTime? Birthday { get; set; } [Display(Name = "任職時間")] public DateTime? TakeOfficeTime { get; set; } [Display(Name = "上次登錄時間")] public DateTime? LastLoginTime { get; set; } [Display(Name = "創建時間")] public DateTime? CreateTime { get; set; } public ICollection<B01_SO> SalseB01_SOs { get; set; } public ICollection<B01_SO> UserB01_SOs { get; set; } } }
Fluent API 配置:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; namespace TestCore.Models { public class TestCoreContext : DbContext { #region 啟用控制台日志 EF Core public static readonly ILoggerFactory MyLoggerFactory = LoggerFactory.Create(builder => { builder.AddConsole(); }); protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder .UseLoggerFactory(MyLoggerFactory); #endregion public TestCoreContext(DbContextOptions<TestCoreContext> options) : base(options) { } public DbSet<User> Users { get; set; } public DbSet<B01_SO> B01_SO { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<B01_SO>() .HasOne(u => u.User) .WithMany(u => u.UserB01_SOs) .HasForeignKey(s => s.UserID) .OnDelete(DeleteBehavior.Restrict) .IsRequired(); modelBuilder.Entity<B01_SO>() .HasOne(u => u.Sales) .WithMany(u => u.SalseB01_SOs) .HasForeignKey(s => s.SaleID) .OnDelete(DeleteBehavior.Restrict) .IsRequired(); } } }