Поделиться через


интеграция .NET AspirePostgreSQLEntity Framework Core

Включает:интеграция хостинга включена интеграция хостинга — и — Client интеграция включенаClient Интеграция

PostgreSQL — это мощная система реляционной базы данных с открытым исходным кодом с много лет активной разработки, которая заработала сильную репутацию для надежности, надежности функций и производительности. Интеграция .NET AspirePostgreSQLEntity Framework Core позволяет подключаться к существующим PostgreSQL базам данных или создавать новые экземпляры с .NET с помощью docker.io/library/postgres образа контейнера.

Интеграция хостинга

Интеграция хостинга PostgreSQL моделирует различные PostgreSQL ресурсы в качестве следующих типов.

Чтобы получить доступ к этим типам и API для представления их в качестве ресурсов в проекте узла приложения, установите пакет NuGet 📦Aspire.Hosting.PostgreSQL:

dotnet add package Aspire.Hosting.PostgreSQL

Дополнительные сведения см. в разделе dotnet add package или Управление зависимостями пакетов в приложениях .NET.

Добавить ресурс сервера PostgreSQL

В проекте узла приложения вызовите AddPostgres в экземпляре builder, чтобы добавить ресурс сервера PostgreSQL, а затем вызовите AddDatabase в экземпляре postgres, чтобы добавить ресурс базы данных, как показано в следующем примере:

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres");
var postgresdb = postgres.AddDatabase("postgresdb");

var exampleProject = builder.AddProject<Projects.ExampleProject>()
                            .WithReference(postgresdb);

// After adding all resources, run the app...

Когда .NET.NET Aspire добавляет контейнерный образ в узел приложения, как показано в предыдущем примере с образом docker.io/library/postgres, он создает новый экземпляр сервера PostgreSQL на локальном компьютере. Ссылка на ваш PostgreSQL сервер и экземпляр базы данных (переменная postgresdb) используется для добавления зависимости к ExampleProject.

При добавлении ресурса базы данных в модель приложения база данных создается, если она еще не существует. Создание базы данных зависит от API-интерфейсов событий узла приложения, в частности ResourceReadyEvent. Другими словами, когда ресурс postgresготов, событие инициируется, и создается ресурс базы данных.

Ресурс сервера PostgreSQL включает учетные данные по умолчанию с username, равным "postgres", и случайно созданными password с использованием метода CreateDefaultPasswordParameter.

Метод WithReference настраивает подключение в ExampleProject с именем "messaging". Дополнительные сведения см. в жизненном цикле ресурсов контейнера .

Совет

Если вы хотите подключиться к существующему серверу PostgreSQL, вызовите AddConnectionString вместо этого. Дополнительные сведения см. в статье "Справочник по существующим ресурсам".

Добавьте ресурс PostgreSQL со скриптами базы данных

По умолчанию при добавлении PostgresDatabaseResourceон использует следующий сценарий для создания базы данных:

CREATE DATABASE "<QUOTED_DATABASE_NAME>"

Чтобы изменить скрипт по умолчанию, выполните цепочку последовательных вызовов метода WithCreationScript на построителе ресурсов базы данных.

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres");

var databaseName = "app_db";
var creationScript = $$"""
    -- Create the database
    CREATE DATABASE {{databaseName}};

    """;

var db = postgres.AddDatabase(databaseName)
                 .WithCreationScript(creationScript);

builder.AddProject<Projects.ExampleProject>()
       .WithReference(db)
       .WaitFor(db);

// After adding all resources, run the app...

В предыдущем примере создается база данных с именем app_db. Скрипт выполняется при создании ресурса базы данных. Скрипт передается в виде строки WithCreationScript в метод, который затем выполняется в контексте PostgreSQL ресурса.

Заметка

Подключение к команде базы данных (\c) не поддерживается при использовании скрипта создания.

Добавьте ресурс pgAdmin PostgreSQL

При добавлении PostgreSQL ресурсов в builder с использованием метода AddPostgres, можно выполнить цепочку вызовов WithPgAdmin для добавления контейнера dpage/pgadmin4. Этот контейнер представляет собой кроссплатформенный клиент для баз данных PostgreSQL, который предоставляет веб-интерфейс для администрирования. Рассмотрим следующий пример:

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres")
                      .WithPgAdmin();

var postgresdb = postgres.AddDatabase("postgresdb");

var exampleProject = builder.AddProject<Projects.ExampleProject>()
                            .WithReference(postgresdb);

// After adding all resources, run the app...

Приведенный выше код добавляет контейнер на основе образа docker.io/dpage/pgadmin4. Контейнер используется для управления ресурсами сервера и базы данных PostgreSQL. Метод WithPgAdmin добавляет контейнер, который служит веб-панелью мониторинга администрирования для PostgreSQL баз данных.

Настройка порта узла pgAdmin

Чтобы настроить порт узла для контейнера pgAdmin, вызовите метод WithHostPort в ресурсе сервера PostgreSQL. В следующем примере показано, как настроить порт узла для контейнера pgAdmin:

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres")
                      .WithPgAdmin(pgAdmin => pgAdmin.WithHostPort(5050));

var postgresdb = postgres.AddDatabase("postgresdb");

var exampleProject = builder.AddProject<Projects.ExampleProject>()
                            .WithReference(postgresdb);

// After adding all resources, run the app...

Приведенный выше код добавляет и настраивает порт узла для контейнера pgAdmin. Порт узла в противном случае назначается случайным образом.

Добавьте ресурс pgWeb PostgreSQL

При добавлении ресурсов PostgreSQL в builder с использованием метода AddPostgres, можно использовать цепочки вызовов для добавления контейнера WithPgWeb через . Этот контейнер представляет собой кроссплатформенный клиент для баз данных PostgreSQL, который предоставляет веб-интерфейс для администрирования. Рассмотрим следующий пример:

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres")
                      .WithPgWeb();

var postgresdb = postgres.AddDatabase("postgresdb");

var exampleProject = builder.AddProject<Projects.ExampleProject>()
                            .WithReference(postgresdb);

// After adding all resources, run the app...

Приведенный выше код добавляет контейнер на основе образа docker.io/sosedoff/pgweb. Все зарегистрированные PostgresDatabaseResource экземпляры используются для создания файла конфигурации для каждого экземпляра, и каждая конфигурация привязана к каталогу закладок контейнера pgweb . Дополнительные сведения см. в документации PgWeb: Server закладки подключений.

Настройка порта узла pgWeb

Чтобы настроить порт узла для контейнера pgWeb, вызовите метод WithHostPort в ресурсе сервера PostgreSQL. В следующем примере показано, как настроить порт узла для контейнера pgAdmin:

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres")
                      .WithPgWeb(pgWeb => pgWeb.WithHostPort(5050));

var postgresdb = postgres.AddDatabase("postgresdb");

var exampleProject = builder.AddProject<Projects.ExampleProject>()
                            .WithReference(postgresdb);

// After adding all resources, run the app...

Приведенный выше код добавляет и настраивает порт узла для контейнера pgWeb. Порт узла в противном случае назначается случайным образом.

Добавьте ресурс сервера PostgreSQL с объемом данных

Чтобы добавить том данных в ресурс сервера PostgreSQL, вызовите метод WithDataVolume в ресурсе сервера PostgreSQL:

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres")
                      .WithDataVolume(isReadOnly: false);

var postgresdb = postgres.AddDatabase("postgresdb");

var exampleProject = builder.AddProject<Projects.ExampleProject>()
                            .WithReference(postgresdb);

// After adding all resources, run the app...

Том данных используется для сохранения данных сервера PostgreSQL за пределами жизненного цикла контейнера. Том данных подключается по пути /var/lib/postgresql/data в контейнере сервера PostgreSQL. Когда параметр name не указан, имя создается случайным образом. Дополнительные сведения об объемах данных и о том, почему они предпочтительнее bind mounts, см. в Docker документации: Томы.

Важный

Некоторые интеграции баз данных, включая интеграцию .NET AspirePostgreSQL, не могут успешно использовать тома данных после развертывания в Azure Container Apps (ACA). Это связано с тем, что ACA использует Server блок сообщений (SMB) для подключения контейнеров к томам данных, а некоторые системы не могут использовать это подключение. Aspire На панели мониторинга база данных, затронутая этой проблемой, имеет состояние "Активация" или "Сбой активации", но никогда не отображается как "Запущен".

Эту проблему можно устранить с помощью управляемой базы данных службыAzure для PostgreSQL размещения развернутой базы данных вместо контейнера в ACA, что является рекомендуемом подходом независимо от этой проблемы. В следующем коде узла приложения показано, как развернуть базу данных в Azure базе данных для PostgreSQL, но в процессе разработки запустить её как контейнер с томом данных.

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddAzurePostgresFlexibleServer("postgres")
                      .RunAsContainer(container => 
                      {
                        container.WithDataVolume();
                      });

builder.Build().Run();

Добавить ресурс сервера PostgreSQL с привязкой данных

Чтобы создать привязку данных к ресурсу сервера PostgreSQL, вызовите метод WithDataBindMount.

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres")
                      .WithDataBindMount(
                          source: @"C:\PostgreSQL\Data",
                          isReadOnly: false);

var postgresdb = postgres.AddDatabase("postgresdb");

var exampleProject = builder.AddProject<Projects.ExampleProject>()
                            .WithReference(postgresdb);

// After adding all resources, run the app...

Важный

Монтажи привязки данных имеют ограниченные функциональные возможности по сравнению с томами, которые обеспечивают более высокую производительность, переносимость и безопасность, что делает их более подходящими для использования в производственных средах. Однако монтирование с привязкой позволяет напрямую получать доступ и изменять файлы на хост-системе, что идеально подходит для разработки и тестирования, в которых требуются изменения в режиме реального времени.

Привязка данных к файловой системе хост-компьютера позволяет сохранять данные сервера PostgreSQL при перезапусках контейнера. Привязанная точка данных монтируется по пути C:\PostgreSQL\Data на Windows (или /PostgreSQL/Data на Unix) на хост-компьютере внутри серверного контейнера PostgreSQL. Дополнительные сведения о привязках точек монтирования данных см. в документации по Docker: привязки точек монтирования.

Добавьте ресурс сервера PostgreSQL с монтированием типа bind для инициализации

Чтобы добавить инициальное подключение через bind mount к ресурсу сервера PostgreSQL, вызовите метод WithInitBindMount:

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres")
                      .WithInitBindMount(@"C:\PostgreSQL\Init");

var postgresdb = postgres.AddDatabase("postgresdb");

var exampleProject = builder.AddProject<Projects.ExampleProject>()
                            .WithReference(postgresdb);

// After adding all resources, run the app...

Подключение привязки init зависит от файловой системы хост-компьютера для инициализации базы данных сервера с помощью папки PostgreSQL контейнеров. Эта папка используется для инициализации и выполнения любых исполняемых скриптов оболочки или файлов команд .sql после создания папки postgres-data. Монтирование привязки init выполнено на C:\PostgreSQL\Init в системе Windows (или на /PostgreSQL/Init в Unix) на пути хост-компьютера в серверном контейнере PostgreSQL.

Добавление ресурса сервера PostgreSQL с параметрами

Если вы хотите явно указать имя пользователя и пароль, используемые образом контейнера, эти учетные данные можно указать в качестве параметров. Рассмотрим следующий альтернативный пример:

var builder = DistributedApplication.CreateBuilder(args);

var username = builder.AddParameter("username", secret: true);
var password = builder.AddParameter("password", secret: true);

var postgres = builder.AddPostgres("postgres", username, password);
var postgresdb = postgres.AddDatabase("postgresdb");

var exampleProject = builder.AddProject<Projects.ExampleProject>()
                            .WithReference(postgresdb);

// After adding all resources, run the app...

Дополнительные сведения о предоставлении параметров см. в разделе "Внешние параметры".

Проведение проверок работоспособности хостинг-интеграции

Интеграция хостинга PostgreSQL автоматически добавляет проверку работоспособности для серверного ресурса PostgreSQL. Проверка работоспособности проверяет, запущен ли сервер PostgreSQL и что к нему можно установить подключение.

Интеграция размещения зависит от пакета NuGet 📦 AspNetCore.HealthChecks.Npgsql.

интеграция Client

Чтобы приступить к .NET AspirePostgreSQLEntity Framework Core интеграции с клиентом, установите пакет NuGet 📦Aspire.Npgsql.EntityFrameworkCore.PostgreSQL в проекте, использующем клиент, то есть в проекте для приложения, использующего PostgreSQL клиент. Интеграция клиента .NET AspirePostgreSQLEntity Framework Core регистрирует нужные экземпляры подклассов DbContext, которые можно использовать для взаимодействия с PostgreSQL.

dotnet add package Aspire.Npgsql.EntityFrameworkCore.PostgreSQL

Добавьте контекст базы данных Npgsql

В файле Program.cs проекта, используемого клиентом, вызовите метод расширения AddNpgsqlDbContext для любой IHostApplicationBuilder, чтобы зарегистрировать подкласс DbContext для использования через контейнер внедрения зависимостей. Метод принимает параметр имени подключения.

builder.AddNpgsqlDbContext<YourDbContext>(connectionName: "postgresdb");

Совет

Параметр connectionName должен соответствовать имени, используемому при добавлении ресурса сервера PostgreSQL в проект узла приложения. Дополнительные сведения см. в разделе "Добавление PostgreSQL ресурса сервера".

После добавления YourDbContext в конструктор, можно получить экземпляр YourDbContext при помощи внедрения зависимостей. Например, чтобы получить объект источника данных из примера службы, определите его как параметр конструктора и убедитесь, что класс ExampleService зарегистрирован в контейнере внедрения зависимостей:

public class ExampleService(YourDbContext context)
{
    // Use context...
}

Дополнительные сведения о внедрении зависимостей см. в разделе .NET внедрения зависимостей.

Обогащение контекста базы данных Npgsql

Вы можете использовать стандартный метод Entity Framework для получения контекста базы данных и добавления его в контейнер внедрения зависимостей:

builder.Services.AddDbContext<YourDbContext>(options =>
    options.UseNpgsql(builder.Configuration.GetConnectionString("postgresdb")
        ?? throw new InvalidOperationException("Connection string 'postgresdb' not found.")));

Заметка

Имя строки подключения, передаваемое методу GetConnectionString, должно соответствовать имени, используемому при добавлении ресурса сервера PostgreSQL в проект узла приложения. Дополнительные сведения см. в разделе "Добавление PostgreSQL ресурса сервера".

У вас больше гибкости при создании контекста базы данных таким образом, например:

  • Вы можете повторно использовать существующий код конфигурации для контекста базы данных, не перезаписывая его для .NET.NET Aspire.
  • Для изменения операций базы данных можно использовать перехватчики Entity Framework Core.
  • Вы можете не использовать пул контекста Entity Framework Core, что может привести к лучшей производительности в некоторых обстоятельствах.

Если вы используете этот метод, вы можете улучшить контекст базы данных с помощью повторных попыток в стиле .NET.NET Aspire, проверок состояния, ведения журнала и телеметрии, вызывая метод EnrichNpgsqlDbContext.

builder.EnrichNpgsqlDbContext<YourDbContext>(
    configureSettings: settings =>
    {
        settings.DisableRetry = false;
        settings.CommandTimeout = 30;
    });

Параметр settings является экземпляром класса NpgsqlEntityFrameworkCorePostgreSQLSettings.

Конфигурация

Интеграция .NET AspirePostgreSQLEntity Framework Core предоставляет несколько подходов к конфигурации и параметров для удовлетворения требований и соглашений проекта.

Используйте строку подключения

При использовании строки подключения из раздела конфигурации ConnectionStrings при вызове метода AddNpgsqlDbContext укажите имя строки подключения:

builder.AddNpgsqlDbContext<MyDbContext>("pgdb");

Строка подключения извлекается из раздела конфигурации ConnectionStrings:

{
  "ConnectionStrings": {
    "pgdb": "Host=myserver;Database=test"
  }
}

EnrichNpgsqlDbContext не будет использовать раздел конфигурации ConnectionStrings, так как ожидается, что DbContext будет зарегистрирован в момент его вызова.

Дополнительные сведения см. в разделе ConnectionString.

Использование поставщиков конфигураций

Интеграция .NET AspirePostgreSQLEntity Framework Core поддерживает Microsoft.Extensions.Configuration. Он загружает NpgsqlEntityFrameworkCorePostgreSQLSettings из файлов конфигурации, таких как appsettings.json с помощью ключа Aspire:Npgsql:EntityFrameworkCore:PostgreSQL. Если вы настроили конфигурации в разделе Aspire:Npgsql:EntityFrameworkCore:PostgreSQL, можно просто вызвать метод без передачи любого параметра.

В следующем примере показан файл appsettings.json, который настраивает некоторые доступные параметры:

{
  "Aspire": {
    "Npgsql": {
      "EntityFrameworkCore": {
        "PostgreSQL": {
          "ConnectionString": "Host=myserver;Database=postgresdb",
          "DisableHealthChecks": true,
          "DisableTracing": true
        }
      }
    }
  }
}

Полную схему интеграции клиента PostgreSQLEntity Framework CoreJSON смотрите в разделе Aspire.Npgsql.EntityFrameworkCore.PostgreSQL/ConfigurationSchema.json.

Использование встроенных делегатов

Вы также можете передать делегат Action<NpgsqlEntityFrameworkCorePostgreSQLSettings> для настройки некоторых или всех параметров внутри кода, например, чтобы задать ConnectionString:

builder.AddNpgsqlDbContext<YourDbContext>(
    "pgdb",
    static settings => settings.ConnectionString = "<YOUR CONNECTION STRING>");

Настройка нескольких классов DbContext

Если вы хотите зарегистрировать несколько DbContext с другой конфигурацией, можно использовать имя раздела конфигурации $"Aspire:Npgsql:EntityFrameworkCore:PostgreSQL:{typeof(TContext).Name}". Конфигурация json будет выглядеть следующим образом:

{
  "Aspire": {
    "Npgsql": {
      "EntityFrameworkCore": {
        "PostgreSQL": {
          "ConnectionString": "<YOUR CONNECTION STRING>",
          "DisableHealthChecks": true,
          "DisableTracing": true,
          "AnotherDbContext": {
            "ConnectionString": "<ANOTHER CONNECTION STRING>",
            "DisableTracing": false
          }
        }
      }
    }
  }
}

Затем вызов метода AddNpgsqlDbContext с параметром типа AnotherDbContext загрузит параметры из раздела Aspire:Npgsql:EntityFrameworkCore:PostgreSQL:AnotherDbContext.

builder.AddNpgsqlDbContext<AnotherDbContext>();

Client проверка состояния интеграции

По умолчанию в интеграциях клиентов .NET.NET Aspire проверки работоспособности включены для всех служб. Аналогичным образом, многие .NET.NET Aspire интеграции хостинга также позволяют проверять работоспособность точек мониторинга. Дополнительные сведения см. в следующем разделе:

По умолчанию интеграция .NET AspirePostgreSQLEntity Framework Core обрабатывает следующие компоненты:

  • Добавляет DbContextHealthCheck, который вызывает метод EF Core из CanConnectAsync. Название проверки состояния системы — это название типа TContext.
  • Интегрируется с конечной точкой HTTP /health, которая указывает, что все зарегистрированные проверки состояния должны успешно пройти, чтобы приложение считалось готовым принять трафик.

Наблюдаемость и телеметрия

.NET .NET Aspire интеграции автоматически настраивают конфигурации журналов, трассировки и метрик, которые иногда называются основными компонентами наблюдаемости. Для получения дополнительной информации о наблюдаемости интеграции и телеметрии см. .NET.NET Aspire обзор интеграции. В зависимости от резервной службы некоторые интеграции могут поддерживать только некоторые из этих функций. Например, некоторые интеграции поддерживают ведение журнала и трассировку, но не метрики. Функции телеметрии также можно отключить с помощью методов, представленных в разделе конфигурации .

Лесозаготовка

Интеграция .NET AspirePostgreSQLEntity Framework Core использует следующие категории журналов:

  • Microsoft.EntityFrameworkCore.ChangeTracking
  • Microsoft.EntityFrameworkCore.Database.Command
  • Microsoft.EntityFrameworkCore.Database.Connection
  • Microsoft.EntityFrameworkCore.Database.Transaction
  • Microsoft.EntityFrameworkCore.Migrations
  • Microsoft.EntityFrameworkCore.Infrastructure
  • Microsoft.EntityFrameworkCore.Migrations
  • Microsoft.EntityFrameworkCore.Model
  • Microsoft.EntityFrameworkCore.Model.Validation
  • Microsoft.EntityFrameworkCore.Query
  • Microsoft.EntityFrameworkCore.Update

Трассировка

Интеграция .NET AspirePostgreSQLEntity Framework Core будет выполнять следующие операции трассировки с помощью OpenTelemetry:

  • Npgsql

Метрика

Интеграция .NET AspirePostgreSQLEntity Framework Core выдает следующие метрики с помощью OpenTelemetry:

  • Microsoft.EntityFrameworkCore:

    • ec_Microsoft_EntityFrameworkCore_active_db_contexts
    • ec_Microsoft_EntityFrameworkCore_total_queries
    • ec_Microsoft_EntityFrameworkCore_queries_per_second
    • ec_Microsoft_EntityFrameworkCore_total_save_changes
    • ec_Microsoft_EntityFrameworkCore_save_changes_per_second
    • ec_Microsoft_EntityFrameworkCore_compiled_query_cache_hit_rate
    • ec_Microsoft_Entity_total_execution_strategy_operation_failures
    • ec_Microsoft_E_execution_strategy_operation_failures_per_second
    • ec_Microsoft_EntityFramew_total_optimistic_concurrency_failures
    • ec_Microsoft_EntityF_optimistic_concurrency_failures_per_second
  • Npgsql:

    • ec_Npgsql_bytes_written_per_second
    • ec_Npgsql_bytes_read_per_second
    • ec_Npgsql_commands_per_second
    • ec_Npgsql_total_commands
    • ec_Npgsql_current_commands
    • ec_Npgsql_failed_commands
    • ec_Npgsql_prepared_commands_ratio
    • ec_Npgsql_connection_pools
    • ec_Npgsql_multiplexing_average_commands_per_batch
    • ec_Npgsql_multiplexing_average_write_time_per_batch

См. также