From d6fc026d91ed7db993722ea99b1894c1cde43e30 Mon Sep 17 00:00:00 2001 From: "Collin M. Barrett" Date: Fri, 19 Jan 2018 11:24:37 -0600 Subject: [PATCH] begin work on InsertOnDuplicateKeyUpdate() wip, but will allow primary data model to be maintained in json on GitHub and the app db to be kept up to date --- src/FilterLists.Api/DbContextExtension.cs | 64 ---------- .../FilterListsDbContextExtensions.cs | 112 ++++++++++++++++++ 2 files changed, 112 insertions(+), 64 deletions(-) delete mode 100644 src/FilterLists.Api/DbContextExtension.cs create mode 100644 src/FilterLists.Data/FilterListsDbContextExtensions.cs diff --git a/src/FilterLists.Api/DbContextExtension.cs b/src/FilterLists.Api/DbContextExtension.cs deleted file mode 100644 index e79ea6811..000000000 --- a/src/FilterLists.Api/DbContextExtension.cs +++ /dev/null @@ -1,64 +0,0 @@ -// https://garywoodfine.com/how-to-seed-your-ef-core-database/ - -using System.Collections.Generic; -using System.IO; -using System.Linq; -using FilterLists.Data; -using FilterLists.Data.Entities; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Newtonsoft.Json; - -namespace FilterLists.Api -{ - public static class DbContextExtension - { - private const string SeedDirectory = "Seed"; - - public static bool AllMigrationsApplied(this DbContext context) - { - var appliedMigrationIds = context.GetService() - .GetAppliedMigrations() - .Select(m => m.MigrationId); - var allMigrationKeys = context.GetService() - .Migrations - .Select(m => m.Key); - return !allMigrationKeys.Except(appliedMigrationIds).Any(); - } - - public static void EnsureSeeded(this FilterListsDbContext context) - { - SeedEntities(context); - SeedJunctions(context); - } - - private static void SeedEntities(DbContext context) - { - Seed(context); - Seed(context); - Seed(context); - Seed(context); - Seed(context); - Seed(context); - } - - private static void SeedJunctions(DbContext context) - { - Seed(context); - Seed(context); - Seed(context); - Seed(context); - Seed(context); - } - - private static void Seed(DbContext dbContext) where T : class - { - if (dbContext.Set().Any()) return; - var rows = JsonConvert.DeserializeObject>( - File.ReadAllText(SeedDirectory + Path.DirectorySeparatorChar + typeof(T).Name + ".json")); - dbContext.AddRange(rows); - dbContext.SaveChanges(); - } - } -} \ No newline at end of file diff --git a/src/FilterLists.Data/FilterListsDbContextExtensions.cs b/src/FilterLists.Data/FilterListsDbContextExtensions.cs new file mode 100644 index 000000000..890523093 --- /dev/null +++ b/src/FilterLists.Data/FilterListsDbContextExtensions.cs @@ -0,0 +1,112 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using FilterLists.Data.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Newtonsoft.Json; + +namespace FilterLists.Data +{ + public static class FilterListsDbContextExtensions + { + private const string SeedDirectory = "Seed"; + + public static bool AllMigrationsApplied(this FilterListsDbContext context) + { + var appliedMigrationIds = context.GetService().GetAppliedMigrations() + .Select(m => m.MigrationId); + var allMigrationKeys = context.GetService().Migrations.Select(m => m.Key); + return !allMigrationKeys.Except(appliedMigrationIds).Any(); + } + + public static void EnsureSeeded(this FilterListsDbContext context) + { + SeedEntities(context); + SeedJunctions(context); + } + + private static void SeedEntities(DbContext context) + { + Seed(context); + Seed(context); + Seed(context); + Seed(context); + Seed(context); + Seed(context); + } + + private static void SeedJunctions(DbContext context) + { + Seed(context); + Seed(context); + Seed(context); + Seed(context); + Seed(context); + } + + private static void Seed(DbContext dbContext) where TEntity : class + { + if (dbContext.Set().Any()) return; + var rows = GetSeedRows(); + dbContext.AddRange(rows); + dbContext.SaveChanges(); + } + + private static List GetSeedRows() + { + return JsonConvert.DeserializeObject>( + File.ReadAllText(SeedDirectory + Path.DirectorySeparatorChar + typeof(TEntity).Name + @".json")); + } + + private static void InsertOnDuplicateKeyUpdate(DbContext dbContext) where TEntity : class + { + var tableName = GetTableName(); + var columnProperties = GetColumnPropertiesLessBaseEntityTimestamps(); + var columns = string.Join(", ", columnProperties.Select(x => x.Name)); + + var rows = GetSeedRows(); + + //TODO: create values query parameter string + //format like: + //('Helen', 24), + //('Katrina', 21) + var values = ""; + foreach (var row in rows) + { + var rowValues = "("; + foreach (var property in columnProperties) + { + } + + rowValues += ")"; + values = values == "" ? rowValues : values + ", " + rowValues; + } + + //TODO: create updates query parameter string + //format like: + //name = VALUES(name), + //age = VALUES(age) + var updates = ""; + + dbContext.Set().FromSql(@"INSERT INTO {0} ({1}) VALUES {2} ON DUPLICATE KEY UPDATE {3}", tableName, + columns, values, updates); + dbContext.SaveChanges(); + } + + private static string GetTableName() where TEntity : class + { + //TODO: handle atypical plural forms (like 'syntaxes') + return typeof(TEntity).Name.ToLower() + "s"; + } + + private static List GetColumnPropertiesLessBaseEntityTimestamps() where TEntity : class + { + return typeof(TEntity).GetProperties().Where(x => + x.PropertyType.Namespace != "System.Collections.Generic" && + !new List {"CreatedDateUtc", "ModifiedDateUtc"}.Contains(x.Name)).ToList(); + } + } +} \ No newline at end of file