diff --git a/src/FilterLists.Data/FilterLists.Data.csproj b/src/FilterLists.Data/FilterLists.Data.csproj index 599cfba3e..cd7900813 100644 --- a/src/FilterLists.Data/FilterLists.Data.csproj +++ b/src/FilterLists.Data/FilterLists.Data.csproj @@ -6,6 +6,7 @@ + diff --git a/src/FilterLists.Data/FilterListsDbContextExtensions.cs b/src/FilterLists.Data/FilterListsDbContextExtensions.cs index 890523093..f80f78a06 100644 --- a/src/FilterLists.Data/FilterListsDbContextExtensions.cs +++ b/src/FilterLists.Data/FilterListsDbContextExtensions.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Reflection; using FilterLists.Data.Entities; +using Humanizer; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; @@ -25,7 +26,9 @@ public static bool AllMigrationsApplied(this FilterListsDbContext context) public static void EnsureSeeded(this FilterListsDbContext context) { SeedEntities(context); + //InsertOnDuplicateKeyUpdateEntities(context); SeedJunctions(context); + //TODO: determine if InsertOnDuplicateKeyUpdateEntities() will work for junctions } private static void SeedEntities(DbContext context) @@ -58,55 +61,71 @@ private static void Seed(DbContext dbContext) where TEntity : class private static List GetSeedRows() { return JsonConvert.DeserializeObject>( - File.ReadAllText(SeedDirectory + Path.DirectorySeparatorChar + typeof(TEntity).Name + @".json")); + File.ReadAllText(SeedDirectory + Path.DirectorySeparatorChar + typeof(TEntity).Name + ".json")); + } + + private static void InsertOnDuplicateKeyUpdateEntities(DbContext context) + { + InsertOnDuplicateKeyUpdate(context); + InsertOnDuplicateKeyUpdate(context); + InsertOnDuplicateKeyUpdate(context); + InsertOnDuplicateKeyUpdate(context); + InsertOnDuplicateKeyUpdate(context); + InsertOnDuplicateKeyUpdate(context); } private static void InsertOnDuplicateKeyUpdate(DbContext dbContext) where TEntity : class { - var tableName = GetTableName(); var columnProperties = GetColumnPropertiesLessBaseEntityTimestamps(); + var tableName = GetTableName(); 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); + var values = CreateValues(columnProperties); + var updates = CreateUpdates(columnProperties); + var rawSqlString = "INSERT INTO " + tableName + " (" + columns + ") VALUES " + values + + " ON DUPLICATE KEY UPDATE " + updates; + dbContext.Set().FromSql(rawSqlString); dbContext.SaveChanges(); } - private static string GetTableName() where TEntity : class + private static string GetTableName() { - //TODO: handle atypical plural forms (like 'syntaxes') - return typeof(TEntity).Name.ToLower() + "s"; + return typeof(TEntity).Name.Pluralize().ToLower(); } - private static List GetColumnPropertiesLessBaseEntityTimestamps() where TEntity : class + private static List GetColumnPropertiesLessBaseEntityTimestamps() { return typeof(TEntity).GetProperties().Where(x => x.PropertyType.Namespace != "System.Collections.Generic" && !new List {"CreatedDateUtc", "ModifiedDateUtc"}.Contains(x.Name)).ToList(); } + + private static string CreateValues(IReadOnlyCollection columnProperties) + { + return GetSeedRows().Select(row => CreateRowValues(columnProperties, row)).Aggregate("", + (current, rowValues) => current == "" ? rowValues : current + ", " + rowValues); + } + + private static string CreateRowValues(IEnumerable columnProperties, TEntity row) + { + return (from property in columnProperties + let value = row.GetType().GetProperty(property.Name).GetValue(row) + select WrapStringPropertyValueInSingleQuotes(property, value)).Aggregate("", + (current, value) => current == "" ? "(" + value : current + ", " + value) + ")"; + } + + private static object WrapStringPropertyValueInSingleQuotes(PropertyInfo property, object value) + { + if (property.PropertyType == typeof(string)) + value = "'" + value + "'"; + return value; + } + + private static string CreateUpdates(IEnumerable columnProperties) + { + //TODO: filter keys out + return columnProperties.Select(property => property.Name).Aggregate("", (current, column) => current == "" + ? column + " = VALUES(" + column + ")" + : current + ", " + column + " = VALUES(" + column + ")"); + } } } \ No newline at end of file