Asp-Net-Core开发笔记:EFCore统一实体和属性命名风格

前言

C# 编码规范中,类和属性都是大写驼峰命名风格(PascalCase / UpperCamelCase),而在数据库中我们往往使用小写蛇形命名(snake_case),在默认情况下,EFCore会把原始的类名和属性名直接映射到数据库,这不符合数据库的命名规范。

为了符合命名规范,而且也为了看起来更舒服,需要自己做命名转换处理。

FreeSQL的命名转换功能

FreeSQL 内置了很方便的命名风格转换功能,只需要设置 UseNameConvert 就可以实现 Pasca Case 到 snake_case 的转换。

c# 复制代码
var fsql = new FreeSqlBuilder()
  .UseConnectionString(DataType.MySql, Default.Value)
  .UseAutoSyncStructure(true)
  .UseNameConvert(NameConvertType.PascalCaseToUnderscoreWithLower)
  .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText))
  .Build();

EFCore 没有内置这个功能,需要我们自行实现。

使用正则实现命名风格转换

使用正则表达式可以实现这个功能

这里来写一个扩展方法

c# 复制代码
public static class StringExt {
    public static string ToSnakeCase(this string input) {
        if (string.IsNullOrEmpty(input)) {
            return input;
        }

        var startUnderscores = Regex.Match(input, @"^_+");
        return startUnderscores + Regex.Replace(input, @"([a-z0-9])([A-Z])", "$1_$2").ToLower();
    }
}

这个方法会在每个小写字母/数字与大写字母之间添加下划线,并把整个字符串转换为小写。

修改 EFCore 行为

EFCore 有非常丰富的功能,修改表名和字段名当然也不在话下。

重写 DbContext 的 OnModelCreating 方法就行

c# 复制代码
public class AppDbContext : DbContext {
  // ...

  protected override void OnModelCreating(ModelBuilder modelBuilder) {
    base.OnModelCreating(modelBuilder);
    modelBuilder.ApplyConfigurationsFromAssembly(GetType().Assembly);

    // CamelCase to SnakeCase
    foreach (var entity in modelBuilder.Model.GetEntityTypes()) {
      // Replace table names
      if (!string.IsNullOrWhiteSpace(entity.GetTableName())) {
        entity.SetTableName(entity.GetTableName()!.ToSnakeCase());
      }

      // Replace column names            
      foreach (var property in entity.GetProperties()) {
        property.SetColumnName(property.GetColumnName().ToSnakeCase());
      }

      foreach (var key in entity.GetKeys()) {
        if (!string.IsNullOrWhiteSpace(key.GetName())) {
          key.SetName(key.GetName()!.ToSnakeCase());
        }
      }

      foreach (var key in entity.GetForeignKeys()) {
        if (!string.IsNullOrWhiteSpace(key.GetConstraintName())) {
          key.SetConstraintName(key.GetConstraintName()!.ToSnakeCase());
        }
      }

      foreach (var index in entity.GetIndexes()) {
        if (!string.IsNullOrWhiteSpace(index.GetDatabaseName())) {
          index.SetDatabaseName(index.GetDatabaseName()!.ToSnakeCase());
        }
      }
    }
  }
}

以上代码会对表名、列名、key、index的名称做转换。

搞定~

参考资料

相关推荐
暴走约伯10 小时前
【VFX工具链源码拆解 02】告别机械劳动(上):一键统改百个子粒子颜色与批量重命名
3d·unity·c#·材质
信息安全失业大专人员12 小时前
每日了解一个智能体-WorkBuddy
开发语言·ai·c#·智能体
呆呆敲代码的小Y12 小时前
【实战精选面试题】C# 面试题详细解答,按难易程度排序
android·java·游戏·c#·游戏开发·unity面试题·c#面试题
淡海水13 小时前
09-01-内存-Unity资源生命周期全景
unity·c#·游戏引擎·.netcore·gc
椒颜皮皮虾྅16 小时前
让 C# 读懂整张图:DeploySharp 驱动 PaddleOCR v4/v5/v6,打通 OCR 全流程
开发语言·人工智能·深度学习·学习·c#·ocr·cuda
昂好的day16 小时前
C# 同步异步与多线程:Thread / Task / 线程池一次讲透(上篇)
开发语言·windows·c#
吃一碗粉只付一碗钱1 天前
12-给SPA友好的401和403响应
c#·状态模式
caimouse1 天前
MonoDevelop 编译用户应用程序时调用的是哪个编译器
c#
will_net1 天前
apollo 站点部署&C#接入
开发语言·c#·apollo