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


    前言#

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

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

    FreeSQL的命名转换功能#

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

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

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

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

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

    这里来写一个扩展方法

    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 有非常丰富的功能,修改表名和字段名当然也不在话下。

    重写 DbContextOnModelCreating 方法就行

    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的名称做转换。

    搞定~

    扩展:使用插件实现名称转换#

    2023-10-10 补充: 本文在博客发表之后,有同学分享了 EFCore.NamingConventions 这个插件,可以很方便的实现命名风格转换

    项目地址: https://github.com/efcore/EFCore.NamingConventions

    使用方式#

    先安装 EFCore.NamingConventions 这个nuget包

    然后重写 DbContext 的 OnConfiguring 方法

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
      base.OnConfiguring(optionsBuilder);
      optionsBuilder.UseSnakeCaseNamingConvention();
    }
    

    一行代码就可以实现名称转换

    这个插件同时支持多种风格的转换,调用不同的扩展方法即可

    • UseSnakeCaseNamingConvention: FullName becomes full_name
    • UseLowerCaseNamingConvention: FullName becomes fullname
    • UseCamelCaseNamingConvention: FullName becomes fullName
    • UseUpperCaseNamingConvention: FullName becomes FULLNAME
    • UseUpperSnakeCaseNamingConvention: FullName becomes FULL_NAME

    参考资料#

  • 相关阅读:
    WPF 笔迹算法 从点集转笔迹轮廓
    Kafka消费者使用案例
    黑客可利用 Windows 容器隔离框架绕过端点安全系统
    A tour of gRPC:05 - gRPC server straming 服务端流
    【MySQL查询常见面试题】如何避免全表扫描
    接入小程序国产操作系统装上双翼
    如何注册一个 DA 为 10 的高价值老域名
    探索比特币符文热:市场趋势与持续性分析
    ES6, ES7, ES8, ES9 以及 ES10 新特征
    Print()函数用法实例详解
  • 原文地址:https://www.cnblogs.com/deali/p/17751279.html