Entity Framework和PostgreSQL:引号问题

5

我所面临的问题与pgAdmin 4中的SQL查询有关。

实体框架(包括其核心版本)会将表格和列名称大写。

这意味着你的SQL代码看起来可能像:

select e."Id", e."Text" from "Entries" e
where e."Text" like '%implicated%'

我在谷歌上搜索了如何防止Entity Framework将名称大写,但没有找到太多有用的信息。
是否有解决方法可以避免在引号中包装表和列名?
提前致谢!

你可以尝试使用[Column("lowerCaseColumnName")]吗? - Vivek Nuna
3个回答

6

很容易完成!


转到OnModelCreating方法。

您需要一个扩展方法(下面共享了代码)

modelBuilder.NamesToSnakeCase();

创建ModelBuilderExtensions类并粘贴以下内容:
public static void NamesToSnakeCase(this ModelBuilder modelBuilder)
{
    foreach (var entity in modelBuilder.Model.GetEntityTypes())
    {
        // Replace table names
        entity.Relational().TableName = entity.Relational().TableName.ToSnakeCase();

        // Replace column names            
        foreach (var property in entity.GetProperties())
        {
            property.Relational().ColumnName = property.Name.ToSnakeCase();
        }

        foreach (var key in entity.GetKeys())
        {
            key.Relational().Name = key.Relational().Name.ToSnakeCase();
        }

        foreach (var key in entity.GetForeignKeys())
        {
            key.Relational().Name = key.Relational().Name.ToSnakeCase();
        }

        foreach (var index in entity.GetIndexes())
        {
            index.Relational().Name = index.Relational().Name.ToSnakeCase();
        }
    }
}

你可以看到StringExtensions类中的ToSnakeCase扩展方法:
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();
}

删除数据库,重新创建迁移,然后运行dotnet ef database update - 完成!

进入图片描述


1
此代码帮助我解决了与Oracle集成的EFCore问题。 - Say

6

针对 EF Core 3 及以上版本

默认情况下,Postgres 将所有表名和列名保存为小写。

某些数据库似乎不需要在 EF Core 中进行任何配置,即可将应用程序中的驼峰命名与数据库中的不区分大小写的名称映射。例如,在 MS SQL Server 上,您可以使用 CamelCased 的应用实体,但在数据库中不区分大小写,一切正常。

然而,在 Postgres 中似乎并非如此,因此需要一些配置

Npgsql 推荐使用这个 NuGet 包 EFCore.NamingConventions,它提供了类似于 @Alex Herman 答案的功能。虽然您不必在每个属性上调用该方法,只需使用一次即可。

有两个地方可以使用它

1. 在您的 DbContext.cs 中

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .UseNpgsql(...)
        .UseLowerCaseNamingConvention();

2. 或者在您的 Startup.cs 文件中

public void ConfigureServices(IServiceCollection services)
{
   services.AddEntityFrameworkNpgsql().AddDbContext<DilaDbContext>(opt => 
       opt.UseNpgsql(
           Configuration.GetConnectionString("DefaultConnection"), 
           b => b.MigrationsAssembly("NameOfAssembly"))
       .UseLowerCaseNamingConvention() // <======== HERE
   ...

Npgsql.org说:

从3.0.0版本开始,您可以使用EFCore.NamingConventions插件自动将所有表和列名设置为snake_case格式:

还包括其他一些命名约定,我使用小写命名约定,因为我用得最多。

他们提供了以下这些约定:

  • UseSnakeCaseNamingConvention:FullName变成full_name
  • UseLowerCaseNamingConvention:FullName变成fullname
  • UseUpperCaseNamingConvention:FullName变成FULLNAME

可能不要使用大写命名约定,因为数据库对象名称中的大写字母会导致EF配置需要引号。


我也遇到了MigrationId重命名的问题,并从以下链接中得到了解决方案:https://github.com/efcore/EFCore.NamingConventions/issues/1 - bluetoothfx
@user1034912,我认为一旦你使用Nuget安装了它,它就应该是EFCore.NamingConventions。 - Max Carroll
我有一个开源项目,我使用这里的 https://github.com/max-carroll/dila/blob/master/DilaAPI/DilaAPI/Startup.cs 创建,你可以看一下我是如何使用它的,我会在有机会时更新答案。 - Max Carroll
只需安装NuGet包EFCore.NamingConventions,这就是你需要做的全部。 - Max Carroll
你正在使用什么版本的EFCore?如果版本低于3.0,可能就是问题所在了。 - Max Carroll
显示剩余2条评论

-4

只需使用小写符号创建您的表和字段。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接