MongoDB Provider para EF Core: As atualizações mais recentes
Avalie esse Artigo
Boas notícias! Conforme confirmado no .local NYC, o provedor do MongoDB para Entity Framework (EF) entrou em disponibilidade geral (GA) com o lançamento da versão 8.0 em NuGet. Os números da versão principal são definidos para se alinharem com o número da versão de .NET e EF para a versão 8.0 significa que o provedor agora suporta oficialmente .NET 8 e EF 8! . . . . . . . . .
Neste artigo, veremos quatro destaques das novidades e como você pode adicionar os recursos aos seus projetos do EF hoje.
Este será um artigo com trechos de código, então pressupõe-se que você tenha algum conhecimento não apenas de MongoDB, mas também de EF. Se você quiser ver um aplicativo de exemplo no Blozor que usa o novo provedor e como começar a implementar as operações CRUD, há um tutorial anterior que escrevi sobre como começar que o orientará de um aplicativo em branco até um sistema funcional .
Se quiser ver o aplicativo de onde os trechos de código deste artigo foram retirados, você pode encontrá-lo no GitHub.
Enquanto o provedor estava em pré-visualização, não foi possível lidar com listas ou documentos incorporados. Mas isso mudou em GA. Agora é tão fácil quanto com o driver MongoDB C# lidar com documentos e arrays incorporados em seu aplicativo.
Na coleção de restaurantes de amostra do MongoDB a partir do conjunto de dados de amostra, os documentos têm um campo de endereço, que é um documento incorporado, e um campo de notas que contém uma array de documentos incorporados representando cada vez que o restaurante foi classificado.
Da mesma forma que antes, você pode ter uma classe de modelo C# que represente os documentos e as classes do restaurante para cada documento incorporado, e o provedor cuidará do mapeamento de e para os documentos do banco de dados para essas classes e os disponibilizará dentro do seu DbSet.
Podemos então acessar as propriedades dessa classe para exibir os dados recuperados do MongoDB usando o provedor.
1 var restaurants = dbContext.Restaurants.AsNoTracking().Take(numOfDocsToReturn).AsEnumerable<Restaurant>(); 2 3 foreach (var restaurant in restaurants) 4 { 5 Console.WriteLine($"{restaurant.Id.ToLower()}: {restaurant.Name} - {restaurant.Borough}, {restaurant.Address.Zipcode}"); 6 foreach (var grade in restaurant.Grades) 7 { 8 Console.WriteLine($"Grade: {grade.GradeLetter}, Score: {grade.Score}"); 9 } 10 Console.WriteLine("--------------------"); 11 }
Este código é bem direto. Ele cria um IEnumerable de restaurantes a partir da consulta ao Dbset, selecionando apenas (usando o método take) o número de documentos de restaurantes solicitados. Em seguida, ele percorre cada restaurante retornado e imprime os dados dele, incluindo o código postal do documento de endereço incorporado.
Como as notas são uma matriz de documentos de notas, também há um loop adicional para acessar os dados de cada documento na matriz.
A criação de documentos também é capaz de suportar documentos incorporados. Como esperado, você pode criar um novo objeto Restaurant e novas versões dos objetos Address e Grade para preencher esses campos também.
1 new Restaurant() 2 { 3 Id = "5678", 4 Name = "My Awesome Restaurant", 5 Borough = "Brooklyn", 6 Cuisine = "American", 7 Address = new Address() 8 { 9 Building = "123", 10 Coord = new double[] { 0, 0 }, 11 Street = "Main St", 12 Zipcode = "11201" 13 }, 14 Grades = new List<Grade>() 15 { 16 new Grade() 17 { 18 Date = DateTime.Now, 19 GradeLetter = "A", 20 Score = 100 21 } 22 }, 23 IsTestData = true, 24 RestaurantId = "123456"
Então, assim como com qualquer código EF, você pode chamar Add no contexto db, passando o objeto para inserir e chamar save changes para sincronizar o contexto db com o armazenamento escolhido — neste caso, o MongoDB.
1 dbContext.Add(newResturant); 2 3 await dbContext.SaveChangesAsync();
Outro novo recurso interessante disponível no GA é a capacidade de obter informações mais detalhadas, para o provedor de registro de sua escolha, sobre o que está acontecendo nos bastidores.
Você pode fazer isso usando os métodos LogTo e EnableSensitiveLogging, disponíveis no DbContextOptionsBuilder no EF. Por exemplo, você pode fazer logon em seu próprio agente, fábrica de log ou até mesmo Console.Write.
1 public static RestaurantDbContext Create(IMongoDatabase database) => 2 new(new DbContextOptionsBuilder<RestaurantDbContext>() 3 .LogTo(Console.WriteLine) 4 .EnableSensitiveDataLogging() 5 .UseMongoDB(database.Client, database.DatabaseNamespace.DatabaseName) 6 .Options);
Uma das razões pelas quais você pode optar por fazer isso, e a razão pela qual ele é tão poderoso, é que ele mostrará qual foi a query subjacente que foi usada para realizar o LINQ solicitado.
Isso pode ser útil para fins de depuração, mas também para aprender mais sobre o MongoDB, além de ver quais campos são mais usados em queries e podem se beneficiar de serem indexados, se ainda não forem um índice.
Outra funcionalidade adicionada que é realmente útil é o suporte para os atributos BSON. Um dos casos de uso mais comuns para isso é permitir o uso de nomes de campo diferentes em seu documento versus o nome da propriedade em sua classe.
Uma das diferenças mais comuns entre documentos MongoDB e propriedades C# está na capitalização. Documentos MongoDB, incluindo campos nos documentos do restaurante, usam minúsculas. Mas em C#, é comum usar camel case. Temos um conjunto de pacotes deconvenções de nomenclatura que você pode usar em seu código para aplicar o tratamento disso em toda a classe, para que você possa especificar uma vez que usará essa convenção, como camel case em seu código, e ela lidará automaticamente com os conversão. Mas, às vezes, só isso não é suficiente.
Por exemplo, nos dados do restaurante, há um campo chamado "restaurant_id" e a convenção de nomenclatura mais comum em C# seria chamar a propriedade de classe "RestaurantId." Como você pode ver, a diferença é mais do que apenas a capitalização. Nesses casos, você pode usar atributos do driver MongoDB subjacente para especificar qual seria o elemento no documento.
1 [ ]2 public string RestaurantId { get; set; }
Outros atributos úteis incluem o atributo
[BsonId]
, para especificar qual propriedade deve ser usada para representar seu campo _id, e [BsonRequired]
, que declara que um campo é obrigatório.Também existem outros atributos BSON, já no driver C#, que estarão disponíveis no provedor em versões futuras, como
[BsonDiscriminator]
e [BsonGuideRepresentation]
.Por último, temos conversores de valor. Eles permitem que você converta o tipo de dados à medida que eles entram e saem do armazenamento.
O que eu mais uso é uma string como tipo para a propriedade Id em vez do tipo de dados ObjectId, pois isso pode ser mais benéfico ao usar estruturas da web como Blazor, em que o front-end utilizará essa propriedade. Antes do GA, você teria que definir sua propriedade Id como ObjectId, como:
1 public ObjectId Id { get; set; }
No entanto, você pode preferir usar string por causa dos métodos relacionados a string disponíveis ou por outros motivos, então agora você pode usar:
1 public string Id { get; set; }
Para habilitar o provedor para lidar com o mapeamento de um valor _id de entrada para o tipo de string, use HasConversion no tipo de entidade.
1 modelBuilder.Entity <Restaurant>() 2 .Property(r => r.Id) 3 .HasConversion<ObjectId>();
Isso significa que, se você quiser, poderá manipular o valor, como convertê-lo em minúsculas com mais facilidade.
1 Console.WriteLine(restaurant.Id.ToLower());
Porém, há uma coisa a ser observada: ao criar documentos/entidades. Embora o MongoDB possa suportar a não especificação de um ID — porque se estiver faltando, um será gerado automaticamente — o EF exige que uma chave não seja nula. Como o campo _id é a chave primária nos documentos do MongoDB, o EF irá cometer um erro ao criar um documento se você não fornecer um ID.
Isso pode ser facilmente resolvido com a criação de um novo ObjectId e a conversão para uma string ao criar um novo documento, como um novo restaurante.
1 Id = new ObjectId().ToString()
Hoje é um grande feito para o Provedor MongoDB oficial da EF Core, mas não é de forma alguma o fim da viajem. O trabalho está apenas começando!
Você leu hoje sobre alguns dos destaques da versão, incluindo conversores de valor, suporte para documentos incorporados e registros detalhados para ver como uma consulta foi gerada e usada nos bastidores. Mas não há apenas mais nesta versão, graças ao trabalho árduo dos engenheiros do MongoDB e da Microsoft, mas mais por vir.
O código do provedor é todo de código aberto para que você possa ver como ele funciona. Mas, melhor ainda, o Readme contém o roteiro, mostrando o que está disponível agora, o que está por vir e o que está fora do escopo.
Além disso, tem um link para onde você pode enviar problemas ou, mais interessante, solicitações de recursos!
Portanto, comece hoje mesmo, aproveitando seu conhecimento existente da EF e do código do aplicativo, enquanto aproveita os benefícios do MongoDB!
Principais comentários nos fóruns
Ainda não há comentários sobre este artigo.