EF从Database First转Code First:如何创建替代EntityObject的BasePOCO类?
从EF Database First迁移到Code First:移除EntityObject并实现BasePOCO类
刚好我之前帮团队完成过类似的迁移,给你梳理一下具体的步骤和注意点:
一、移除业务实体类的EntityObject继承
Database First生成的实体类会自动继承EntityObject,但Code First的POCO类不需要这个EF专属基类,你需要做这些清理:
- 直接删除每个实体类的
: EntityObject继承声明 - 移除
EntityObject自带的冗余属性,比如EntityKey、EntityState,还有自动生成的OnPropertyChanging/OnPropertyChanged方法(如果不需要手动管理变更追踪,EF Code First会自动处理) - 给实体类补充Code First需要的映射配置,要么用数据注解,要么后续用Fluent API。举个例子:
// 原来的Database First实体 public class Customer : EntityObject { public EntityKey CustomerKey { get; set; } public string CustomerName { get; set; } } // 修改后的Code First POCO public class Customer { [Key] // 标记主键,符合EF约定也可以省略 public int CustomerId { get; set; } [MaxLength(100)] // 指定字段长度 public string CustomerName { get; set; } }
二、创建替代EntityObject的BasePOCO类
EntityObject的核心能力是属性变更通知和实体状态追踪,我们可以通过实现INotifyPropertyChanged来复刻这些功能,同时加入通用审计属性(可选):
using System.ComponentModel; using System.Runtime.CompilerServices; using System.Collections.Generic; public class BasePOCO : INotifyPropertyChanged { // 可选:通用审计字段,比如创建/更新时间 public DateTime CreatedAt { get; set; } public DateTime UpdatedAt { get; set; } // 手动实体状态追踪(如果需要替代EntityObject的EntityState) public EntityState EntityState { get; set; } = EntityState.Unchanged; // 实现属性变更通知 public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } // 通用属性设置方法,简化变更通知代码 protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null) { if (EqualityComparer<T>.Default.Equals(field, value)) return false; field = value; OnPropertyChanged(propertyName); return true; } }
之后让所有业务实体继承这个基类,比如:
public class Customer : BasePOCO { [Key] public int CustomerId { get; set; } private string _customerName; public string CustomerName { get => _customerName; set => SetProperty(ref _customerName, value); // 自动触发变更通知 } }
三、配置Code First的DbContext
最后需要创建DbContext来管理实体和数据库的映射:
using Microsoft.EntityFrameworkCore; public class AppDbContext : DbContext { // 声明所有业务实体的DbSet public DbSet<Customer> Customers { get; set; } // 其他实体... // 配置数据库连接 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer("你的数据库连接字符串"); } // 可选:用Fluent API替代数据注解做更灵活的映射 protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Customer>() .Property(c => c.CustomerName) .HasMaxLength(100); // 其他实体的映射规则... } }
四、验证迁移
- 打开Package Manager Console,运行
Add-Migration InitialCreate生成迁移脚本,检查脚本是否和原数据库结构匹配 - 如果是已有数据库,建议先用
Update-Database -Script生成SQL脚本,手动确认后再执行,避免数据丢失
内容的提问来源于stack exchange,提问作者crazyTech
相关产品推荐
相关产品推荐

