You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:56:34