EF Core如何将简单字符串列表映射至数据库表?
EF Core映射字符串集合到外部表(无需新增实体类)
原C#实体类
public class Test { public int Id { get; set; } private readonly List<string> _helpers = new(); public IEnumerable<string> Helpers => _helpers; }
NHibernate中的映射方式
在NHibernate里,可通过Fluent配置将Helpers属性映射到外部表,代码如下:
// 使用Fluent NHibernate配置 HasMany(gt => gt.Helpers) .Access.CamelCaseField(Prefix.Underscore) .AsBag() .Table("OtherTable") // 存储Helpers集合的表 .KeyColumn("ForeignKey") // 指向Test表的外键列 .Element("DB_Column_name") // 存储单个Helper字符串的列名 .Not.LazyLoad() .Cascade.All();
问题
已知EF Core支持“owned”实体集合,如何在不创建新类存储字符串的前提下,将Helpers暴露的字符串集合映射至另一表的列?
EF Core实现方案
EF Core没有直接对应NHibernate中Element的原生API,但可以通过值对象集合机制间接实现,无需额外创建实体类:
1. 调整实体类(可选,用于变更跟踪)
因为Helpers是只读的IEnumerable<string>,若需要EF Core跟踪集合变化,建议添加集合操作方法:
public class Test { public int Id { get; set; } private readonly List<string> _helpers = new(); public IEnumerable<string> Helpers => _helpers; public void AddHelper(string helper) { _helpers.Add(helper); } public void RemoveHelper(string helper) { _helpers.Remove(helper); } }
2. Fluent API配置映射
在DbContext的OnModelCreating方法中完成配置:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Test>(entity => { // 配置Test表主键 entity.HasKey(t => t.Id); // 配置Helpers集合映射到外部表 entity.OwnsMany(t => t.Helpers, builder => { // 指定存储集合的表名 builder.ToTable("OtherTable"); // 配置指向Test表的外键列 builder.WithOwner().HasForeignKey("ForeignKey"); // 指定存储字符串的列名 builder.Property<string>("Value").HasColumnName("DB_Column_name"); // 配置集合的组合主键(EF Core要求值对象集合必须有主键) builder.HasKey("ForeignKey", "Value"); // 关闭延迟加载 builder.Navigation(x => x).AutoInclude(); // 配置级联删除 builder.WithOwner().OnDelete(DeleteBehavior.Cascade); }); // 让EF Core直接访问私有字段_helpers entity.Navigation(t => t.Helpers).UsePropertyAccessMode(PropertyAccessMode.Field); }); }
关键配置说明
UsePropertyAccessMode(PropertyAccessMode.Field):对应NHibernate的Access.CamelCaseField,让EF Core直接访问私有集合字段WithOwner().HasForeignKey("ForeignKey"):对应NHibernate的KeyColumn,配置关联外键Property<string>("Value").HasColumnName("DB_Column_name"):对应NHibernate的Element,指定存储字符串的列名AutoInclude():对应NHibernate的Not.LazyLoad(),关闭延迟加载OnDelete(DeleteBehavior.Cascade):对应NHibernate的Cascade.All(),配置级联操作
内容的提问来源于stack exchange,提问作者Luis Abreu
相关产品推荐
相关产品推荐

