Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Esta página documenta a API e as alterações de comportamento que têm o potencial de interromper a atualização de aplicativos existentes do Entity Framework Core 8 para o Entity Framework Core 9. Certifique-se de verificar as alterações interruptivas anteriores se estiver atualizando a partir de uma versão anterior do Entity Framework Core:
- Alterações interruptivas no EF Core 8
- Alterações interruptivas no EF Core 7
- Alterações interruptivas no EF Core 6
Estrutura de Destino
O Entity Framework 9 tem como destino o .NET 8. Isso significa que os aplicativos existentes que têm como destino o .NET 8 podem continuar a fazê-lo. Os aplicativos que têm como alvo versões mais antigas do .NET, .NET Core e .NET Framework precisarão ter como destino o .NET 8 ou o .NET 9 para usar o Entity Framework Core 9.
Resumo
Observação
Se você estiver usando o Azure Cosmos DB, consulte a seção separada abaixo sobre alterações interruptivas do Azure Cosmos DB.
Alterações de alto impacto
A exceção será gerada ao aplicar migrações se houver alterações de modelo pendentes
Acompanhamento de problema nº 33732
Comportamento antigo
Se o modelo tiver alterações pendentes em comparação com a última migração, estas alterações não serão aplicadas juntamente com o restante das migrações quando Migrate for chamado.
Novo comportamento
A partir do EF Core 9.0, se o modelo tiver alterações pendentes em comparação com a última migração, uma exceção será gerada quando dotnet ef database update, Migrate ou MigrateAsync for chamado:
O modelo de contexto "DbContext" tem alterações pendentes. Adicione uma nova migração antes de atualizar o banco de dados. Essa exceção pode ser suprimida ou registrada passando a ID do Evento 'RelationalEventId.PendingModelChangesWarning' para o método 'ConfigureWarnings' em 'DbContext.OnConfiguring' ou 'AddDbContext'.
Por que
Esquecer de adicionar uma nova migração depois de fazer alterações de modelo é um erro comum que pode ser difícil de diagnosticar em alguns casos. A nova exceção garante que o modelo do aplicativo corresponda ao banco de dados após a aplicação das migrações.
Mitigações
Há várias situações comuns quando essa exceção pode ser gerada:
Não há migrações. Isso é comum quando o banco de dados é atualizado por outros meios.
- Mitigação: se você não planeja usar migrações para gerenciar o esquema de banco de dados, remova a chamada Migrate ou MigrateAsync, senão adicione uma migração.
Há pelo menos uma migração, mas o instantâneo do modelo está ausente. Isso é comum para migrações criadas manualmente.
- Mitigação: Adicionar uma nova migração usando ferramentas do EF, isso atualizará o instantâneo do modelo.
O modelo não foi modificado pelo desenvolvedor, mas é criado de forma não determinística, fazendo com que o EF o detecte como modificado. Isso é comum quando
new DateTime(),DateTime.Now,DateTime.UtcNowouGuid.NewGuid()são usados em objetos fornecidos para HasData.- Mitigação: adicione uma nova migração, examine seu conteúdo para localizar a causa e substitua os dados dinâmicos por um valor estático e codificado no modelo. A migração deverá ser recriada depois que o modelo for corrigido. Se dados dinâmicos precisarem ser usados para semeadura, considere usar o novo padrão de semeadura em vez de HasData.
A última migração foi criada para um provedor diferente do usado para aplicar as migrações.
- Mitigação: Este é um cenário sem suporte. O aviso pode ser suprimido usando o snippet de código abaixo, mas esse cenário provavelmente deixará de funcionar em uma versão futura do EF Core. A solução recomendada é gerar um conjunto separado de migrações para cada provedor.
As migrações são geradas, modificadas ou escolhidas dinamicamente substituindo alguns dos serviços EF.
-
Mitigação: o aviso é um falso positivo nesse caso e deveria ser suprimido:
options.ConfigureWarnings(w => w.Ignore(<xref:Microsoft.EntityFrameworkCore.Diagnostics.RelationalEventId.PendingModelChangesWarning>))
-
Mitigação: o aviso é um falso positivo nesse caso e deveria ser suprimido:
Você está usando ASP.NET Core Identity e alterando opções que afetam o modelo, como:
.AddDefaultIdentity<ApplicationUser>(options => { options.Stores.SchemaVersion = IdentitySchemaVersions.Version2; options.Stores.MaxLengthForKeys = 256; options.SignIn.RequireConfirmedAccount = false; })Mitigação: para garantir que as opções sejam aplicadas consistentemente, o aplicativo precisa ser especificado como o projeto de inicialização ao executar as ferramentas EF ou, como alternativa,
IDesignTimeDbContextFactoryprecisa ser implementado no projeto que contém :DbContextpublic class DatabaseContextDesignTimeFactory : IDesignTimeDbContextFactory<DatabaseContext> { public DatabaseContext CreateDbContext(string[] args) { var services = new ServiceCollection(); AddIdentity(services); var serviceProvider = services.BuildServiceProvider(); var optionsBuilder = new DbContextOptionsBuilder<DatabaseContext>(); optionsBuilder.UseApplicationServiceProvider(serviceProvider); optionsBuilder.UseSqlServer(); return new DatabaseContext(optionsBuilder.Options); } public static IServiceCollection AddIdentity(IServiceCollection services) { services.AddDefaultIdentity<ApplicationUser>(options => { options.Stores.SchemaVersion = IdentitySchemaVersions.Version2; options.Stores.MaxLengthForKeys = 256; options.SignIn.RequireConfirmedAccount = false; }) .AddRoles<IdentityRole>() .AddEntityFrameworkStores<DatabaseContext>(); return services; } }
Se o seu cenário não se enquadrar em nenhum dos casos acima e adicionar uma nova migração criar a mesma migração sempre ou uma migração vazia e a exceção ainda for gerada, crie um pequeno projeto de reprodução e compartilhe-a com a equipe do EF em um novo problema.
A exceção é gerada ao aplicar migrações em uma transação explícita
Acompanhamento do problema nº 17578
Comportamento antigo
Para aplicar migrações de modo resiliene, o seguinte padrão era comumente usado:
await dbContext.Database.CreateExecutionStrategy().ExecuteAsync(async () =>
{
await using var transaction = await dbContext.Database.BeginTransactionAsync(cancellationToken);
await dbContext.Database.MigrateAsync(cancellationToken);
await transaction.CommitAsync(cancellationToken);
});
Novo comportamento
A partir do EF Core 9.0, as chamadas Migrate e MigrateAsync iniciarão uma transação e executarão os comandos usando um ExecutionStrategy e, se o aplicativo usar o padrão acima, uma exceção será gerada:
Um erro foi gerado para o aviso 'Microsoft.EntityFrameworkCore.Migrations.MigrationsUserTransactionWarning': Uma transação foi iniciada antes da aplicação das migrações. Isso impede a aquisição de um bloqueio de banco de dados e, portanto, o banco de dados não será protegido contra aplicativos de migração simultâneos. As transações e a estratégia de execução já são gerenciadas pelo EF, conforme necessário. Remova a transação externa. Essa exceção pode ser suprimida ou registrada passando a ID de evento 'RelationalEventId.MigrationsUserTransactionWarning' para o método 'ConfigureWarnings' em 'DbContext.OnConfiguring' ou 'AddDbContext'.
Por que
O uso de uma transação explícita impede que um bloqueio de banco de dados seja adquirido e, portanto, o banco de dados não será protegido contra aplicativos de migração simultâna, limitando também a forma que o EF pode gerenciar as transações internamente.
Mitigações
Se houver apenas uma chamada de banco de dados dentro da transação, remova a transação externa e ExecutionStrategy:
await dbContext.Database.MigrateAsync(cancellationToken);
Caso contrário, se o cenário exigir uma transação explícita e você tiver outro mecanismo em vigor para impedir o aplicativo de migração simultâneo, ignore o aviso:
options.ConfigureWarnings(w => w.Ignore(RelationalEventId.MigrationsUserTransactionWarning))
Alterações de impacto médio
Microsoft.EntityFrameworkCore.Design não encontrado ao usar ferramentas do EF
Acompanhamento do problema nº 35265
Comportamento antigo
Previamente, as ferramentas de EF exigiam que Microsoft.EntityFrameworkCore.Design fossem referenciadas da maneira a seguir.
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="*.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Novo comportamento
A partir do SDK do .NET 9.0.200, uma exceção é gerada quando uma ferramenta EF é invocada:
Não foi possível carregar o arquivo ou o assembly 'Microsoft.EntityFrameworkCore.Design, Culture=neutral, PublicKeyToken=null'. O sistema não pode encontrar o arquivo especificado.
Por que
As ferramentas de EF dependiam de um comportamento não documentado do SDK do .NET que fazia com que ativos privados fossem incluídos no arquivo de .deps.json gerado. Isso foi corrigido no sdk#45259. Infelizmente, a alteração do EF para considerar isso não atende aos critérios de manutenção do EF 9.0.x, portanto, ela será implementada no EF 10.
Mitigações
Como uma solução alternativa antes do lançamento do EF 10, você pode marcar a referência do assembly Design como publicável:
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<Publish>true</Publish>
</PackageReference>
Isso o incluirá no arquivo .deps.json gerado, mas tem o efeito colateral de copiar o Microsoft.EntityFrameworkCore.Design.dll para as pastas de destino e de publicação.
Alterações de baixo impacto
EF.Functions.Unhex() agora retorna byte[]?
Acompanhamento do problema #33864
Comportamento antigo
A função EF.Functions.Unhex() foi anotada anteriormente para retornar byte[].
Novo comportamento
A partir do EF Core 9.0, Unhex() agora é anotada para retornar byte[]?.
Por que
Unhex() é traduzido para a função SQLite unhex , que retorna NULL para entradas inválidas. Como resultado, Unhex() retornou null para esses casos, violando a anotação.
Mitigações
Se você tiver certeza se o conteúdo de texto passado Unhex() representa uma cadeia de caracteres hexadecimal válida, basta adicionar o operador tolerante a nulo como uma declaração de que a invocação nunca retornará nulo:
var binaryData = await context.Blogs.Select(b => EF.Functions.Unhex(b.HexString)!).ToListAsync();
Caso contrário, adicione verificações de runtime para nulo no valor de retorno de Unhex().
Modelos compilados agora referenciam métodos de conversor de valor diretamente
Problema de acompanhamento nº 35033
Comportamento antigo
Anteriormente, ao usar conversores de valor com modelos compilados (usando dotnet ef dbcontext optimize), o EF referenciava o tipo de conversor e tudo funcionava corretamente.
public sealed class BooleanToCharConverter() : ValueConverter<bool, char>(v => ConvertToChar(v), v => ConvertToBoolean(v))
{
public static readonly BooleanToCharConverter Default = new();
private static char ConvertToChar(bool value) // Private method
=> value ? 'Y' : 'N';
private static bool ConvertToBoolean(char value) // Private method
=> value == 'Y';
}
Novo comportamento
A partir do EF Core 9.0, o EF gera um código que faz referência diretamente aos próprios métodos de conversão. Se esses métodos forem privados, a compilação falhará.
Por que
Essa alteração foi necessária para dar suporte a NativeAOT.
Mitigações
Torne os métodos referenciados por conversores de valor públicos ou internos em vez de privados.
Aridade dos argumentos de nulidade da SqlFunctionExpression validada
Acompanhamento do problema #33852
Comportamento antigo
Anteriormente, era possível criar um SqlFunctionExpression com um número diferente de argumentos e argumentos de propagação de nulidade.
Novo comportamento
A partir do EF Core 9.0, o EF agora lança uma exceção se o número de argumentos e os argumentos de propagação de nulidade não corresponderem.
Por que
O fato de não haver correspondência entre o número de argumentos e os argumentos de propagação de nulidade pode levar a um comportamento inesperado.
Mitigações
Certifique-se de que o argumentsPropagateNullability tenha o mesmo número de elementos que o arguments. Em caso de dúvida, use false como argumento de nulabilidade.
ToString() agora retorna uma string vazia para instâncias de null
Acompanhamento de problema nº 33941
Comportamento antigo
Anteriormente, o EF retornava resultados inconsistentes para o método ToString() quando o valor do argumento era null. Por exemplo, ToString() na propriedade bool? com valor bool? retornava null, mas para expressões bool? que não são de propriedade cujo valor era null, retornava True. O comportamento também era inconsistente para outros tipos de dados, por exemplo, ToString() na enumeração de valor null retornava uma string vazia.
Novo comportamento
A partir do EF Core 9.0, o método ToString() agora retorna consistentemente uma string vazia em todos os casos em que o valor do argumento é null.
Por que
O comportamento antigo era inconsistente em diferentes tipos de dados e situações, além de não estar alinhado com o comportamento de C#.
Mitigações
Para reverter para o comportamento antigo, reescreva a consulta conforme necessário:
var newBehavior = context.Entity.Select(x => x.NullableBool.ToString());
var oldBehavior = context.Entity.Select(x => x.NullableBool == null ? null : x.NullableBool.ToString());
As dependências de estrutura compartilhada foram atualizadas para 9.0.x
Comportamento antigo
Os aplicativos que usam o SDK Microsoft.NET.Sdk.Web e direcionam para o net8.0 resolveriam pacotes como System.Text.Json, Microsoft.Extensions.Caching.Memory, Microsoft.Extensions.Configuration.Abstractions, Microsoft.Extensions.Logging e Microsoft.Extensions.DependencyModel na estrutura compartilhada. Desse modo, esses assemblies normalmente não seriam implantados com o aplicativo.
Novo comportamento
Embora o EF Core 9.0 ainda dê suporte ao net8.0, ele agora faz referência às versões 9.0.x de System.Text.Json, Microsoft.Extensions.Caching.Memory, Microsoft.Extensions.Configuration.Abstractions, Microsoft.Extensions.Logging e Microsoft.Extensions.DependencyModel. Os aplicativos que direcionam para o net8.0 não poderão aproveitar a estrutura compartilhada para evitar a implantação desses assemblies.
Por que
As versões de dependência correspondentes contêm as correções de segurança mais recentes e usá-las simplifica o modelo de manutenção do EF Core.
Mitigações
Altere seu aplicativo para direcionar ao net9.0 para obter o comportamento anterior.
Alterações interruptivas do Azure Cosmos DB
Um trabalho extensivo foi feito para aprimorar o provedor do Azure Cosmos DB na versão 9.0. As alterações incluem uma série de alterações significativas de alto impacto; se você estiver atualizando um aplicativo existente, leia o seguinte com atenção.
Alterações de alto impacto
A propriedade discriminatória agora é chamada de $type em vez de Discriminator
Acompanhamento de problema nº 34269
Comportamento antigo
O EF adiciona automaticamente uma propriedade discriminatória a documentos JSON para identificar o tipo de entidade que o documento representa. Nas versões anteriores do EF, essa propriedade JSON costumava ser nomeada Discriminator por padrão.
Novo comportamento
A partir do EF Core 9.0, a propriedade discriminatória agora é chamada de $type por padrão. Se você tiver documentos existentes no Azure Cosmos DB de versões anteriores do EF, eles usarão a nomenclatura antiga Discriminator e, após a atualização para o EF 9.0, as consultas com esses documentos falharão.
Por que
Uma prática JSON emergente usa uma propriedade $type em cenários em que o tipo de um documento precisa ser identificado. Por exemplo, o System.Text.Json do .NET também oferece suporte ao polimorfismo, usando $type como seu nome de propriedade discriminatória padrão (documentos). Para se alinhar com o restante do ecossistema e facilitar a interoperação com ferramentas externas, o padrão foi alterado.
Mitigações
A mitigação mais fácil é simplesmente configurar o nome da propriedade discriminatória para ser Discriminator, assim como antes de usar HasDiscriminator:
modelBuilder.Entity<Session>().HasDiscriminator<string>("Discriminator");
Ao fazer isso para todos os tipos de entidade de nível superior, o EF se comportará exatamente como antes.
Neste ponto, se preferir, você também pode atualizar todos os seus documentos para usar a nova $type nomenclatura.
A propriedade id agora contém apenas a propriedade de chave EF por padrão
Acompanhamento de problema nº 34179
Comportamento antigo
Antes, o EF inseria o valor discriminatório do tipo de entidade na propriedade id do documento. Por exemplo, se você tiver salvo um tipo de entidade Blog com uma propriedade Id que contém 8, a propriedade JSON id conterá Blog|8.
Novo comportamento
A partir do EF Core 9.0, a propriedade JSON id não contém mais o valor discriminatório e contém apenas o valor da propriedade de chave. Para o exemplo acima, a propriedade JSON id seria simplesmente 8. Se você tiver documentos existentes no Azure Cosmos DB de versões anteriores do EF, eles terão o valor discriminatório na propriedade JSON id e, após a atualização para o EF 9.0, as consultas com esses documentos falharão.
Por que
Como a propriedade JSON id deve ser exclusiva, o discriminador era adicionado anteriormente para permitir a existência de entidades diferentes com o mesmo valor de chave. Por exemplo, isso permitiu ter Blog e Post com uma propriedade Id contendo o valor 8 dentro do mesmo contêiner e partição. Isso se alinhou melhor com os padrões de modelagem de dados de banco de dados relacional, em que cada tipo de entidade é mapeado para sua própria tabela e, portanto, tem seu próprio espaço de chaves.
O EF 9.0 geralmente alterava o mapeamento para ficar mais alinhado com as práticas e expectativas NoSQL comuns do Azure Cosmos DB, em vez de corresponder às expectativas dos usuários que vêm de bancos de dados relacionais. Além disso, a presença do valor discriminador na propriedade id tornou mais difícil para ferramentas e sistemas externos interagirem com documentos JSON gerados pelo EF; esses sistemas externos geralmente não são cientes dos valores discriminatórios do EF, que são derivados de tipos .NET por padrão.
Mitigações
A mitigação mais fácil é simplesmente configurar o EF para incluir o discriminador na propriedade JSON id , como antes de usar HasDiscriminatorInJsonId. Uma nova opção de configuração foi introduzida para essa finalidade:
modelBuilder.Entity<Session>().HasDiscriminatorInJsonId();
Ao fazer isso para todos os tipos de entidade de nível superior, o EF se comportará exatamente como antes.
Neste ponto, se preferir, você também pode atualizar todos os seus documentos para reescrever sua propriedade JSON id. Observe que isso só será possível se entidades de tipos diferentes não compartilharem o mesmo valor de id no mesmo contêiner.
A propriedade JSON id é mapeada para a chave
Acompanhamento de problema nº 34179
Comportamento antigo
Anteriormente, o EF criava uma propriedade de sombra mapeada para a propriedade JSON id, a menos que alguma das propriedades fosse mapeada explicitamente para id.
Novo comportamento
A partir do EF Core 9, a propriedade de chave será mapeada por convenção para a propriedade JSON id, se possível. Isso significa que a propriedade da chave não será mais mantida no documento com um nome diferente e o mesmo valor, portanto, o código que não for do EF que consome os documentos e depende da presença dessa propriedade não funcionará mais corretamente.
Por que
O EF 9.0 alterou de forma geral o mapeamento para estar mais alinhado com as práticas e expectativas comuns do NoSQL do Azure Cosmos DB. E não é comum armazenar o valor da chave duas vezes no documento.
Mitigações
Se você quiser preservar o comportamento do EF Core 8, a mitigação mais fácil será usar HasShadowId, uma nova opção de configuração que foi introduzida para esta finalidade:
modelBuilder.Entity<Session>().HasShadowId();
Ao fazer isso para todos os tipos de entidade de nível superior, o EF se comportará exatamente como antes. Ou você pode aplicá-lo a todos os tipos de entidade no modelo com uma chamada usando HasShadowIds:
modelBuilder.HasShadowIds();
Alterações de impacto médio
A sincronização de E/S por meio do provedor Azure Cosmos DB não tem mais suporte
Rastreamento do problema #32563
Comportamento antigo
Anteriormente, chamar métodos síncronos como ToList ou SaveChanges fazia com que o EF Core bloqueasse de forma síncrona usando .GetAwaiter().GetResult() ao executar chamadas assíncronas contra o SDK do Azure Cosmos DB. Isso pode resultar em deadlock.
Novo comportamento
A partir do EF Core 9.0, o EF agora gera uma exceção por padrão ao tentar usar a E/S síncrona. A mensagem de exceção é "O Azure Cosmos DB não tem suporte para E/S síncrona. Certifique-se de usar e aguardar corretamente apenas métodos assíncronos ao usar o Entity Framework Core para acessar o Azure Cosmos DB. Consulte https://aka.ms/ef-cosmos-nosync para obter mais informações."
Por que
O bloqueio síncrono em métodos assíncronos pode resultar em deadlock, e o SDK do Azure Cosmos DB só dá suporte para métodos assíncronos.
Mitigações
No EF Core 9.0, o erro pode ser suprimido com:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.ConfigureWarnings(w => w.Ignore(CosmosEventId.SyncNotSupported));
}
Dito isso, os aplicativos devem parar de usar APIs de sincronização com o Azure Cosmos DB, pois não há suporte para isso no SDK do Azure Cosmos DB. A capacidade de suprimir a exceção será removida em uma versão futura do EF Core, após a qual a única opção será usar APIs assíncronas.
As consultas SQL agora devem projetar valores JSON diretamente
Acompanhamento de problema nº 25527
Comportamento antigo
Antes, o EF gerava consultas como as seguintes:
SELECT c["City"] FROM root c
Essas consultas fazem com que o Azure Cosmos DB envolva cada resultado em um objeto JSON, da seguinte forma:
[
{
"City": "Berlin"
},
{
"City": "México D.F."
}
]
Novo comportamento
A partir do EF Core 9.0, o EF agora adiciona o modificador VALUE às consultas da seguinte forma:
SELECT VALUE c["City"] FROM root c
Essas consultas fazem com que o Azure Cosmos DB retorne os valores diretamente, sem serem envolvidos:
[
"Berlin",
"México D.F."
]
Se o aplicativo usar consultas SQL, essas consultas provavelmente serão interrompidas após a atualização para o EF 9.0, pois não incluem o modificador VALUE.
Por que
Envolver cada resultado em um objeto JSON adicional pode causar degradação do desempenho em alguns cenários, inchar a carga do resultado JSON e não é a maneira natural de trabalhar com o Azure Cosmos DB.
Mitigações
Para mitigar, basta adicionar o modificador VALUE às projeções de suas consultas SQL, conforme mostrado acima.
Os resultados indefinidos agora são filtrados automaticamente a partir dos resultados da consulta
Acompanhamento de problema nº 25527
Comportamento antigo
Antes, o EF gerava consultas como as seguintes:
SELECT c["City"] FROM root c
Essas consultas fazem com que o Azure Cosmos DB envolva cada resultado em um objeto JSON, da seguinte forma:
[
{
"City": "Berlin"
},
{
"City": "México D.F."
}
]
Se algum dos resultados fosse indefinido (por exemplo, a propriedade City estava ausente no documento), um documento vazio era retornado e o EF retornava null para esse resultado.
Novo comportamento
A partir do EF Core 9.0, o EF agora adiciona o modificador VALUE às consultas da seguinte forma:
SELECT VALUE c["City"] FROM root c
Essas consultas fazem com que o Azure Cosmos DB retorne os valores diretamente, sem serem envolvidos:
[
"Berlin",
"México D.F."
]
O comportamento do Azure Cosmos DB é filtrar undefined os valores dos resultados automaticamente; isso significa que, se uma das propriedades City estiver ausente no documento, a consulta retornará um único resultado, em vez de dois resultados, sendo um deles null.
Por que
Envolver cada resultado em um objeto JSON adicional pode causar degradação do desempenho em alguns cenários, inchar a carga do resultado JSON e não é a maneira natural de trabalhar com o Azure Cosmos DB.
Mitigações
Se a obtenção null de valores para resultados indefinidos for importante para o seu aplicativo, una os valores undefined para null usando o novo EF.Functions.Coalesce operador:
var users = await context.Customer
.Select(c => EF.Functions.CoalesceUndefined(c.City, null))
.ToListAsync();
As consultas traduzidas incorretamente não são mais traduzidas
Acompanhamento de problema nº 34123
Comportamento antigo
Antes, o EF traduzia consultas como as seguintes:
var sessions = await context.Sessions
.Take(5)
.Where(s => s.Name.StartsWith("f"))
.ToListAsync();
No entanto, a tradução SQL para esta consulta estava incorreta:
SELECT c
FROM root c
WHERE ((c["Discriminator"] = "Session") AND STARTSWITH(c["Name"], "f"))
OFFSET 0 LIMIT @__p_0
No SQL, a cláusula WHERE é avaliada antes das cláusulas OFFSET e LIMIT; mas na consulta LINQ acima, o operador Take aparece antes do operador Where. Isso pode fazer com que essas consultas retornem resultados incorretos.
Novo comportamento
A partir do EF Core 9.0, essas consultas não são mais traduzidas e uma exceção é gerada.
Por que
Traduções incorretas podem causar corrupção silenciosa de dados, o que pode introduzir bugs difíceis de descobrir em seu aplicativo. O EF sempre prefere falhar rapidamente mediante um lançamento em vez de possivelmente causar corrupção de dados.
Mitigações
Se você estava satisfeito com o comportamento anterior e gostaria de executar o mesmo SQL, basta trocar a ordem dos operadores LINQ:
var sessions = await context.Sessions
.Where(s => s.Name.StartsWith("f"))
.Take(5)
.ToListAsync();
Infelizmente, o Azure Cosmos DB não dá suporte às cláusulas OFFSET e LIMIT em subconsultas SQL no momento, que é o que a tradução adequada da consulta LINQ original exige.
Alterações de baixo impacto
HasIndex agora é lançado em vez de ignorado
Acompanhamento de problema nº 34023
Comportamento antigo
Anteriormente, as chamadas para HasIndex eram ignoradas pelo provedor EF do Cosmos DB.
Novo comportamento
O provedor agora é lançado se HasIndex for especificado.
Por que
No Azure Cosmos DB, todas as propriedades são indexadas por padrão e nenhuma indexação precisa ser especificada. Embora seja possível definir uma política de indexação personalizada, isso não tem suporte do EF no momento e pode ser feito por meio do Portal do Azure sem suporte do EF. Como as chamadas HasIndex não estavam fazendo nada, elas não são mais permitidas.
Mitigações
Remova quaisquer chamadas para HasIndex.
IncludeRootDiscriminatorInJsonId foi renomeado para HasRootDiscriminatorInJsonId após o 9.0.0-rc.2
Acompanhamento de problema nº 34717
Comportamento antigo
A API IncludeRootDiscriminatorInJsonId foi introduzida na versão 9.0.0 rc.1.
Novo comportamento
Para a versão final do EF Core 9.0, a API foi renomeada para HasRootDiscriminatorInJsonId
Por que
Outra API relacionada foi renomeada para começar em Has vez de Include, e esta também foi renomeada para consistência.
Mitigações
Se o código estiver usando a API IncludeRootDiscriminatorInJsonId, basta alterá-lo para referenciar HasRootDiscriminatorInJsonId.