.NET迁移报错:实体类型List<int>需定义主键,求解决方案
问题描述
我在使用.NET进行数据迁移时遇到问题。
定义的抽象类:
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } public string Name { get; set; } [ForeignKey("UserId")] public int UserId { get; set; } public DateTime? DateTime { get; set; } public virtual User User { get; set; }
随后创建了两个派生实体类:
public class MovieFavoriteList:FavoriteListBase<int> { public List<int> MovieIds { get; set; } } public class TvSeriesFavoriteList:FavoriteListBase<int> { public List<int> TvIds { get; set; } }
执行迁移时出现错误:
The entity type 'List
' requires a primary key to be defined. If you intended to use a keyless entity type, call 'HasNoKey' in 'OnModelCreating'.
我曾尝试给TvSeriesFavoriteList添加[Keyless]特性,但这种做法并不合理,想请教如何解决该问题?
解决方案
EF Core无法直接将List<int>这类集合类型映射为数据库表的字段,它会把集合当成独立实体类型,因此提示需要主键。提供两种可行解决方式:
方法一:用值转换器将集合序列化为字符串
通过EF Core的值转换器,把List<int>序列化为JSON字符串存在数据库单个字段中,读取时再反序列化为集合。
在DbContext的OnModelCreating方法中配置:
protected override void OnModelCreating(ModelBuilder modelBuilder) { // 配置MovieFavoriteList的MovieIds字段 modelBuilder.Entity<MovieFavoriteList>() .Property(x => x.MovieIds) .HasConversion( v => JsonSerializer.Serialize(v, (JsonSerializerOptions)null), v => JsonSerializer.Deserialize<List<int>>(v, (JsonSerializerOptions)null) ); // 配置TvSeriesFavoriteList的TvIds字段 modelBuilder.Entity<TvSeriesFavoriteList>() .Property(x => x.TvIds) .HasConversion( v => JsonSerializer.Serialize(v, (JsonSerializerOptions)null), v => JsonSerializer.Deserialize<List<int>>(v, (JsonSerializerOptions)null) ); }
这种方式适合无需对集合单个元素做查询的简单场景。
方法二:创建关联实体实现多对多关系
如果需要对收藏的电影/电视剧ID做单独查询(比如统计某部电影的收藏量),推荐用标准多对多关系设计:
- 创建中间实体:
// 电影收藏中间表实体 public class MovieFavorite { [Key] public int Id { get; set; } public int MovieFavoriteListId { get; set; } public int MovieId { get; set; } public virtual MovieFavoriteList MovieFavoriteList { get; set; } } // 电视剧收藏中间表实体 public class TvSeriesFavorite { [Key] public int Id { get; set; } public int TvSeriesFavoriteListId { get; set; } public int TvId { get; set; } public virtual TvSeriesFavoriteList TvSeriesFavoriteList { get; set; } }
- 修改派生实体类,替换集合类型:
public class MovieFavoriteList:FavoriteListBase<int> { public virtual List<MovieFavorite> MovieFavorites { get; set; } = new List<MovieFavorite>(); } public class TvSeriesFavoriteList:FavoriteListBase<int> { public virtual List<TvSeriesFavorite> TvSeriesFavorites { get; set; } = new List<TvSeriesFavorite>(); }
- 在
OnModelCreating中配置关系:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<MovieFavorite>() .HasOne(f => f.MovieFavoriteList) .WithMany(l => l.MovieFavorites) .HasForeignKey(f => f.MovieFavoriteListId); modelBuilder.Entity<TvSeriesFavorite>() .HasOne(f => f.TvSeriesFavoriteList) .WithMany(l => l.TvSeriesFavorites) .HasForeignKey(f => f.TvSeriesFavoriteListId); }
这种方式符合关系型数据库设计规范,支持更灵活的数据查询操作。
内容的提问来源于stack exchange,提问作者user19344428
相关产品推荐
相关产品推荐

