Entity Framework 7.0.9:为多对多关联表添加额外列的方法
为EF 7.0.9多对多关联表添加额外字段的实现方案
可行性说明
完全可行。EF 7中,仅通过UsingEntity指定表名的隐式多对多关联表无法添加额外字段,必须将关联表转为显式实体类,通过配置一对多关系来实现带额外字段的多对多关联。
具体实现步骤
1. 创建显式关联实体类
新增TemplateOption类,对应数据库中的TemplateOptions表,包含原有的复合主键及新增的Value字段:
using System.ComponentModel.DataAnnotations.Schema; namespace SelfService.Portal.Core.API.Models { public class TemplateOption { [Column(Order = 0)] public Guid TemplateId { get; set; } [Column(Order = 1)] public Guid OptionId { get; set; } [Column(Order = 2)] public string Value { get; set; } // 导航属性 public TemplateModel Template { get; set; } public OptionModel Option { get; set; } } }
注:若需要将
BaseModel中的审计字段(Created、Modified等)加入关联表,可让TemplateOption继承BaseModel,但需调整主键配置(复合主键+审计字段)。
2. 修改原有实体的导航属性
将OptionModel和TemplateModel中的多对多导航属性,改为指向TemplateOption的集合:
修改后的OptionModel
using System.ComponentModel.DataAnnotations.Schema; namespace SelfService.Portal.Core.API.Models { public class OptionModel : BaseModel { [Column(Order = 1)] public string Name { get; set; } [Column(Order = 2)] public string OptionType { get; set; } [Column(Order = 3)] public string OptionValue { get; set; } // 替换原有导航属性 public ICollection<TemplateOption> TemplateOptions { get; set; } } }
修改后的TemplateModel
using System.Text.Json.Serialization; namespace SelfService.Portal.Core.API.Models { public class TemplateModel : BaseModel { public string Name { get; set; } public string Version { get; set; } public string Description { get; set; } public string JSONData { get; set; } // 替换原有导航属性 public ICollection<TemplateOption> TemplateOptions { get; set; } } }
3. 更新DbContext的Fluent API配置
删除原有的隐式多对多配置,改为配置TemplateOption与两个主实体的一对多关系,并指定复合主键:
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // 配置TemplateOption的复合主键 modelBuilder.Entity<TemplateOption>() .HasKey(to => new { to.TemplateId, to.OptionId }); // 配置Template与TemplateOption的一对多关系 modelBuilder.Entity<TemplateModel>() .HasMany(t => t.TemplateOptions) .WithOne(to => to.Template) .HasForeignKey(to => to.TemplateId) .OnDelete(DeleteBehavior.Cascade); // 配置Option与TemplateOption的一对多关系 modelBuilder.Entity<OptionModel>() .HasMany(o => o.TemplateOptions) .WithOne(to => to.Option) .HasForeignKey(to => to.OptionId) .OnDelete(DeleteBehavior.Cascade); }
注:原配置中
j => j.HasKey("EnvironmentId", "DomainId")为错误配置,已修正为正确的复合主键TemplateId和OptionId。
4. 生成并执行EF迁移
通过Package Manager Console或.NET CLI生成迁移并更新数据库:
- Package Manager Console:
Add-Migration AddValueColumnToTemplateOptions Update-Database - .NET CLI:
dotnet ef migrations add AddValueColumnToTemplateOptions dotnet ef database update
执行完成后,数据库中的TemplateOptions表将新增Value字段,结构与预期一致。
内容的提问来源于stack exchange,提问作者Torsten Brendgen
相关产品推荐
相关产品推荐

