如何更改 EF Core 与 postgresql 数据库的通信方式

问题描述 投票:0回答:1

我正在使用 ASP.NET Core MVC 和 postgresql 来编写应用程序,但是当运行这段代码时:

public async Task<IActionResult> Index()
{
    return _context.antrenorler != null 
                 ? View(await _context.antrenorler.ToListAsync()) 
                 : Problem("Entity set 'YazlabDbContext.antrenorler' is null.");
}

Entity Framework Core 运行此 SQL 查询:

SELECT a.id, a.adsoyad, a."contactInfo", a.experience, a.specialties
FROM antrenorler AS a

在我的数据库上,但(pgadmin4)一直说列

a.id
不存在。现在我知道 Entity Framework Core 更喜欢 SQL Server,但我需要让 EF Core 以适合 PostgreSQL 的方式运行查询。

数据库连接成功。我需要做的就是更改查询格式,但我不知道如何更改。

编辑:这是确切的错误消息

fail: Microsoft.EntityFrameworkCore.Database.Command[20102]
      Failed executing DbCommand (469ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT a.id, a.adsoyad, a."contactInfo", a.experience, a.specialties
      FROM antrenorler AS a
fail: Microsoft.EntityFrameworkCore.Query[10100]
      An exception occurred while iterating over the results of a query for context type 'YAZLAB2.YazlabDbContext'.
      Npgsql.PostgresException (0x80004005): 42703: column a.id does not exist

      POSITION: 8
         at Npgsql.Internal.NpgsqlConnector.<ReadMessage>g__ReadMessageLong|223_0(NpgsqlConnector connector, Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
         at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
         at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
         at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
         at Npgsql.NpgsqlCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken)
         at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
        Exception data:
          Severity: ERROR
          SqlState: 42703
          MessageText: column a.id does not exist
          Position: 8
          File: parse_relation.c
          Line: 3661
          Routine: errorMissingColumn
      Npgsql.PostgresException (0x80004005): 42703: column a.id does not exist
postgresql entity-framework-core asp.net-core-mvc
1个回答
0
投票

您不需要为数据库添加任何别名。 EF 并不偏爱某一数据库而不是其他数据库,但如果您使用 Identity 进行身份验证,则生成的架构将使用 PascalCase。它是提供程序,在您的例子中是 NPGSql,用于构建数据库的 SQL 以从 linq 表达式执行。

默认情况下,SQL 生成将期望实体属性名称与表列名称匹配。如果您的 antrenorler 表不包含“id”列,而是使用 antrenorlerId 之类的内容,那么您有几个选择:

1- 更新您的实体定义以匹配表列:

[Key]
public int antrenorlerId { get; protected set; }

2- 告诉 EF 它应该使用不同的列名称:

[Key, Column("antrenorler_id")]
public int id { get; protected set; }

使用 PostgreSQL,您经常会遇到属性名称的 Snake_case 问题。这可能导致需要指定要在每个属性中使用的名称。或者,您可以拦截属性名称解析器,该解析器处理属性和数据库列之间的来回转换以处理 Snake_case,而不是在实体中使用该命名约定。此方法的示例:(https://andrewlock.net/customising-asp-net-core-identity-ef-core-naming-conventions-for-postgresql/)

大多数时候,当我使用 PostgreSQL 时,我只是使用

[Column]
属性,因为它充当比较模式和实体时易于引用的文档,而不是在运行时执行翻译的“神奇”代码。

© www.soinside.com 2019 - 2024. All rights reserved.