Поставщик Cosmos DB в Entity Framework Core выбрасывает 400 BadRequest
Я интегрировал Cosmos DB в свой проект ASP.NET Core API, используя последний пакет EF Core, который поставляется с поставщиком Cosmos DB.
Я могу успешно использовать этого провайдера при локальном запуске в моем локальном кластере ASF при подключении к локальному экземпляру эмулятора Cosmos DB. Однако при попытке выполнить локальный ASF или ASF, размещенный в Azure, я не могу подключиться к экземпляру Azure Cosmos DB. По какой-то причине я продолжаю получать 400 BadRequest при инициализации начального числа для базы данных / коллекции.
Это следующая строка, которая генерирует ошибку:
var created = await context.Database.EnsureCreatedAsync();
Исключение:
BadRequest в Microsoft.EntityFrameworkCore.Cosmos.Storage.Internal.CosmosClient.CreateDocumentCollectionIfNotExistsOnceAsync(DbContext _, String collectionId, CancellationToken cancellationToken)
в Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementationAsync [TState, TResult] (Func4 operation, Func
4 verifySucceeded, TState state, CancellationToken cancellationToken)
в Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementationAsync [TState, TResult] (Func4 operation, Func
4 verifySucceeded, состояние TState, CancellationToken cancellationToken) в Microsoft.EntityFrameworkCore.Cosmos.Storage.Internal.CosmosDatabaseCreator.EnsureCreatedAsync(CancellationToken cancellationToken) в Infrastructure.SystemDataContextSextConjectStext.TextStext.TextStext.SetenStext.TextStext.TextStext.Text.Text.Text.Text.Text.Text.Text.Text.Text..Text..Te..Te..Te....Te..Te....Te..Te....Te....Te...Te....T..En....T..En........T..En..Te.............T..Ente..............Аты........T..Seed(IWebHost webhost) в Extensions\IWebHostExtensions.cs: строка 23 в Api.<> C__DisplayClass1_0.b__1(String url, прослушиватель AspNetCoreCommunicationListener) в AccountApi.cs: строка 47 в Microsoft.ServiceFabric.Sorevices.mun.Core.Net.Core.Core.Com OpenAsync(CancellationToken cancellationToken) в Microsoft.ServiceFabric.Services.Runtime.StatelessServiceInstanceAdapter.OpenCommunicationListenersAsync(CancellationToken cancellationToken)
Что я пробовал:
- Анализируя логику аналитики, не показывает логи для этих запросов
- Удаление EnsureCreated и просто напрямую вставить данные
- Создать коллекцию вручную (SystemDataContext)
- Создать базу данных вручную (AccountService)
- Удаление сетевого брандмауэра (разрешить все сети) в Azure
Используемые данные конечной точки имеют вид:
"Cosmos": {
"EndPoint": "https://xxxx-sqlapi.documents.azure.com:443",
"AuthKey": "xxx==",
"DatabaseName": "AccountService"
},
Метод расширения для подключения провайдера Cosmos DB:
public static IServiceCollection AddCosmosSettings(this IServiceCollection services, IConfiguration configuration)
{
services.AddEntityFrameworkCosmos()
.AddDbContext<SystemDataContext>(options =>
{
options.UseCosmos(configuration["Cosmos:EndPoint"], configuration["Cosmos:AuthKey"], configuration["Cosmos:DatabaseName"]); ;
},
ServiceLifetime.Scoped //Showing explicitly that the DbContext is shared across the HTTP request scope (graph of objects started in the HTTP request)
);
return services;
}
Любые идеи с благодарностью!
2 ответа
Для справки, провайдер базы данных Cosmos в EF Core 2.2 является предварительным вариантом и не подходит для использования с базой данных Cosmos DB, размещенной в Azure. Это связано с тем, что в некоторых местах отсутствуют заголовки, которые, по-видимому, не являются проблемой для эмулятора, но вызывают 400 при выполнении exe для Azure.
Проблема, которую я рассматривал дольше всего, заключалась в том, что я получил 400, когда пытался создать коллекцию документов. Покопавшись в исходном коде EF Core, я увидел, что он не отправлял ключи разделов. На самом деле в текущей реализации Cosmos DB реализации ключей разделения вообще нет. И поскольку я создал базу данных в Azure с общей пропускной способностью для всех коллекций, очевидно, вы должны предоставить ключ раздела на уровне коллекции.
Я получил эту ошибку с недавно созданной учетной записью CosmosDB. Некоторые вещи работали, но я также получал такие ошибки, как эта 400 для вызова EF Core EnsureCreated(), а также 404 при попытке пропустить это и просто .SaveChanges ().
В итоге я удалил эту учетную запись CosmosDB и создал новую, на этот раз все работало нормально.
Я использовал Microsoft.EntityFrameworkCore.Cosmos (6.0.0).
Да, и я создал новую учетную запись CosmosDB в группе ресурсов «Default-Web-EastUS», тогда как предыдущая попытка использовала учетную запись «Default-Storage-EastUS». Я сомневаюсь, что это имеет значение, но хотел все записать, на случай, если в будущем мне придется гуглить свой собственный ответ ;-)