【问题标题】:Entity Framework and PostgreSQL: quotation marks issueEntity Framework 和 PostgreSQL:引号问题
【发布时间】:2018-11-24 13:39:59
【问题描述】:

我面临的问题是 pgAdmin 4 中的 SQL 查询。

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

这意味着您的 SQL 将类似于

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

我在谷歌上搜索防止实体框架大写名称的方法,但没有发现太多。

是否有避免将表名和列名括在引号中的解决方法?

提前致谢!

【问题讨论】:

  • 你能试试[Column(“lowerCaseolumnName”)]吗?

标签: postgresql entity-framework entity-framework-core


【解决方案1】:

轻松搞定!


转到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();
        }
    }
}

你可以看到ToSnakeCase扩展方法——这里是StringExtensions类:

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 - bingo!

【讨论】:

  • 这段代码帮助我解决了 EFCore 与 oracle 集成的问题。
【解决方案2】:

对于 EF Core 3 及更高版本

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

某些数据库似乎不需要任何 EF Core 配置,以便将应用程序中的 Camel 大小写名称映射到数据库中不区分大小写的名称。例如,使用 MS SQL Server,您可以使用 CamelCased 来处理应用程序实体,但在数据库中您不会对它们进行大小写,一切正常。

对于 Postgres,情况似乎并非如此,因此需要一些 configuration

Npgsql recommend 这个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:全名变成全名
  • UseLowerCaseNamingConvention:全名变成全名
  • UseUpperCaseNamingConvention: 全名变成全名

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

【讨论】:

  • 也遇到过 MigrationId 重命名问题并从以下链接获得解决方案:github.com/efcore/EFCore.NamingConventions/issues/1
  • Intellisaense 不起作用。你能至少输入你使用了什么“使用.....”吗?
  • @user1034912,我认为一旦你使用 nuget 安装它,它就会是 EFCore.NamingConventions
  • 我在这里创建了一个开源项目github.com/max-carroll/dila/blob/master/DilaAPI/DilaAPI/…,你可以看看我是如何使用它的,有机会我会更新答案
  • 只需安装 nuget 包 `EFCore.NamingConventions` 就可以了
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-30
    • 1970-01-01
    • 1970-01-01
    • 2020-11-18
    • 2016-01-01
    • 2013-12-25
    相关资源
    最近更新 更多