diff --git a/src/AzureIoTHub.Portal.Infrastructure/PortalDbContext.cs b/src/AzureIoTHub.Portal.Infrastructure/PortalDbContext.cs index a5f8c0a26..34378ff04 100644 --- a/src/AzureIoTHub.Portal.Infrastructure/PortalDbContext.cs +++ b/src/AzureIoTHub.Portal.Infrastructure/PortalDbContext.cs @@ -8,6 +8,7 @@ namespace AzureIoTHub.Portal.Infrastructure using AzureIoTHub.Portal.Infrastructure.Seeds; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; + using Microsoft.Extensions.Logging; public class PortalDbContext : DbContext { @@ -19,22 +20,5 @@ public PortalDbContext(DbContextOptions options) : base(options) { } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - base.OnModelCreating(modelBuilder); - - try - { - var config = this.Database.GetService(); - - _ = modelBuilder - .MigrateDeviceModelProperties(config); - } - catch (InvalidOperationException) - { - - } - } } } diff --git a/src/AzureIoTHub.Portal.Infrastructure/Seeds/DeviceModelPropertySeeder.cs b/src/AzureIoTHub.Portal.Infrastructure/Seeds/DeviceModelPropertySeeder.cs new file mode 100644 index 000000000..7a0075194 --- /dev/null +++ b/src/AzureIoTHub.Portal.Infrastructure/Seeds/DeviceModelPropertySeeder.cs @@ -0,0 +1,47 @@ +// Copyright (c) CGI France. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace AzureIoTHub.Portal.Infrastructure.Seeds +{ + using Azure.Data.Tables; + using AzureIoTHub.Portal.Domain; + using AzureIoTHub.Portal.Domain.Entities; + using AzureIoTHub.Portal.Models; + using AzureIoTHub.Portal.Infrastructure.Factories; + using Microsoft.EntityFrameworkCore; + + internal static class DeviceModelPropertySeeder + { + public static async Task MigrateDeviceModelProperties(this PortalDbContext ctx, ConfigHandler config) + { + var table = new TableClientFactory(config.StorageAccountConnectionString) + .GetDeviceTemplateProperties(); + + var set = ctx.Set(); + + foreach (var item in table.Query().ToArray()) + { + if (await set.AnyAsync(c => c.Id == item.RowKey)) + continue; + +#pragma warning disable CS8629 // Nullable value type may be null. + _ = await set.AddAsync(new DeviceModelProperty + { + Id = item.RowKey, + ModelId = item.PartitionKey, + Name = item.GetString(nameof(DeviceModelProperty.Name)), + DisplayName = item.GetString(nameof(DeviceModelProperty.DisplayName)), + PropertyType = Enum.Parse(item.GetString(nameof(DeviceModelProperty.PropertyType))), + Order = item.GetInt32(nameof(DeviceModelProperty.Order)) ?? 0, + IsWritable = item.GetBoolean(nameof(DeviceModelProperty.IsWritable)).Value + }); +#pragma warning restore CS8629 // Nullable value type may be null. + + if (config is ProductionConfigHandler) + { + _ = await table.DeleteEntityAsync(item.PartitionKey, item.RowKey); + } + } + } + } +} diff --git a/src/AzureIoTHub.Portal.Infrastructure/Seeds/DeviceModelPropoertySeeder.cs b/src/AzureIoTHub.Portal.Infrastructure/Seeds/DeviceModelPropoertySeeder.cs deleted file mode 100644 index 3fed6b5c7..000000000 --- a/src/AzureIoTHub.Portal.Infrastructure/Seeds/DeviceModelPropoertySeeder.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) CGI France. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace AzureIoTHub.Portal.Infrastructure.Seeds -{ - using Azure.Data.Tables; - using AzureIoTHub.Portal.Domain; - using AzureIoTHub.Portal.Domain.Entities; - using AzureIoTHub.Portal.Models; - using AzureIoTHub.Portal.Infrastructure.Factories; - using Microsoft.EntityFrameworkCore; - - internal static class DeviceModelPropoertySeeder - { - public static ModelBuilder MigrateDeviceModelProperties(this ModelBuilder modelBuilder, ConfigHandler config) - { - var table = new TableClientFactory(config.StorageAccountConnectionString) - .GetDeviceTemplateProperties(); - - foreach (var item in table.Query().ToArray()) - { -#pragma warning disable CS8629 // Nullable value type may be null. - _ = modelBuilder.Entity() - .HasData(new DeviceModelProperty - { - Id = item.RowKey, - ModelId = item.PartitionKey, - Name = item.GetString(nameof(DeviceModelProperty.Name)), - DisplayName = item.GetString(nameof(DeviceModelProperty.DisplayName)), - PropertyType = Enum.Parse(item.GetString(nameof(DeviceModelProperty.PropertyType))), - Order = item.GetInt32(nameof(DeviceModelProperty.Order)) ?? 0, - IsWritable = item.GetBoolean(nameof(DeviceModelProperty.IsWritable)).Value - }); -#pragma warning restore CS8629 // Nullable value type may be null. - - if (config is ProductionConfigHandler) - { - _ = table.DeleteEntity(item.PartitionKey, item.RowKey); - } - } - - return modelBuilder; - } - } -} diff --git a/src/AzureIoTHub.Portal/Server/Startup.cs b/src/AzureIoTHub.Portal/Server/Startup.cs index 4e0883f70..30f2ea6d2 100644 --- a/src/AzureIoTHub.Portal/Server/Startup.cs +++ b/src/AzureIoTHub.Portal/Server/Startup.cs @@ -17,6 +17,7 @@ namespace AzureIoTHub.Portal.Server using AzureIoTHub.Portal.Infrastructure; using AzureIoTHub.Portal.Infrastructure.Factories; using AzureIoTHub.Portal.Infrastructure.Repositories; + using AzureIoTHub.Portal.Infrastructure.Seeds; using Extensions; using Hellang.Middleware.ProblemDetails; using Hellang.Middleware.ProblemDetails.Mvc; @@ -36,6 +37,7 @@ namespace AzureIoTHub.Portal.Server using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; + using Microsoft.Extensions.Logging; using Microsoft.Extensions.Primitives; using Microsoft.OpenApi.Models; using Models.v10; @@ -439,8 +441,21 @@ private static async Task EnsureDatabaseCreatedAndUpToDate(IApplicationBuilder a { using var scope = app.ApplicationServices.CreateScope(); using var context = scope.ServiceProvider.GetRequiredService(); + var config = scope.ServiceProvider.GetRequiredService(); await context.Database.MigrateAsync(); + + try + { + await context + .MigrateDeviceModelProperties(config); + + _ = await context.SaveChangesAsync(); + } + catch (InvalidOperationException e) + { + scope.ServiceProvider.GetRequiredService().LogError(e, "Failed to seed the database."); + } } } }