From 7c3d0c2dada10d405a352fd0d0d775c3c902e9e0 Mon Sep 17 00:00:00 2001 From: Collin Barrett Date: Mon, 10 Sep 2018 17:24:49 -0500 Subject: [PATCH] refactors closes #308 --- .../Extensions/SeedFilterListsDbContext.cs | 74 +++++++++++-------- 1 file changed, 42 insertions(+), 32 deletions(-) diff --git a/src/FilterLists.Data/Seed/Extensions/SeedFilterListsDbContext.cs b/src/FilterLists.Data/Seed/Extensions/SeedFilterListsDbContext.cs index 021be6563..75bbf33ac 100644 --- a/src/FilterLists.Data/Seed/Extensions/SeedFilterListsDbContext.cs +++ b/src/FilterLists.Data/Seed/Extensions/SeedFilterListsDbContext.cs @@ -34,19 +34,12 @@ public static void SeedOrUpdate(this FilterListsDbContext dbContext, string data private static void SeedOrUpdate(this DbContext dbContext, string dataPath) where TEntity : class, IBaseEntity { - var entityType = dbContext.Model.FindEntityType(typeof(TEntity)); - var properties = GetPropertiesLessValueGeneratedTimestamps(entityType); - var seedRows = GetSeedRows(dataPath); - ApplyRemovals(dbContext, seedRows); - InsertOnDuplicateKeyUpdate(dbContext, properties, entityType, seedRows); + var seed = GetSeed(dataPath); + ApplyRemovals(dbContext, seed); + InsertOnDuplicateKeyUpdate(dbContext, seed); } - private static List GetPropertiesLessValueGeneratedTimestamps(IEntityType entityType) => - entityType.GetProperties() - .Where(x => !new List {"CreatedDateUtc", "ModifiedDateUtc"}.Contains(x.Name)) - .ToList(); - - private static List GetSeedRows(string dataPath) where TEntity : IBaseEntity + private static List GetSeed(string dataPath) where TEntity : IBaseEntity { try { @@ -60,32 +53,44 @@ private static List GetSeedRows(string dataPath) where TEntity } } - //https://stackoverflow.com/a/52264468/2343739 - private static void ApplyRemovals(DbContext dbContext, IEnumerable seedRows) + private static void ApplyRemovals(DbContext dbContext, IEnumerable seed) where TEntity : class { - var entityType = dbContext.Model.FindEntityType(typeof(TEntity)); - var entityPk = entityType.FindPrimaryKey(); - var dbEntity = Expression.Parameter(entityType.ClrType, "e"); - var matchAny = seedRows.Select(e => entityPk.Properties - .Select(p => Expression.Equal( - Expression.Property(dbEntity, p.PropertyInfo), - Expression.Property(Expression.Constant(e), p.PropertyInfo))) - .Aggregate(Expression.AndAlso)) - .Aggregate(null, - (current, match) => - current != null ? Expression.OrElse(current, match) : match); - var notInSeedRows = Expression.Lambda>(Expression.Not(matchAny), dbEntity); - var removedEntities = dbContext.Set().Where(notInSeedRows); + var removedEntities = GetRemovedEntities(dbContext, seed); dbContext.RemoveRange(removedEntities); dbContext.SaveChanges(); } - private static void InsertOnDuplicateKeyUpdate(DbContext dbContext, - IReadOnlyCollection properties, IEntityType entityType, IEnumerable seedRows) + //https://stackoverflow.com/a/52264468/2343739 + private static IEnumerable GetRemovedEntities(DbContext dbContext, IEnumerable seed) + where TEntity : class + { + var entityType = dbContext.Model.FindEntityType(typeof(TEntity)); + var dbEntity = Expression.Parameter(entityType.ClrType, "e"); + var matchesAnyPk = GetMatchesAnyPk(seed, entityType, dbEntity); + var notInSeed = Expression.Lambda>(Expression.Not(matchesAnyPk), dbEntity); + return dbContext.Set().Where(notInSeed); + } + + private static Expression GetMatchesAnyPk(IEnumerable seed, IEntityType entityType, + Expression dbEntity) + where TEntity : class => + seed.Select(e => entityType.FindPrimaryKey() + .Properties + .Select(p => Expression.Equal( + Expression.Property(dbEntity, p.PropertyInfo), + Expression.Property(Expression.Constant(e), p.PropertyInfo))) + .Aggregate(Expression.AndAlso)) + .Aggregate(null, + (Func)((current, match) => + current != null ? Expression.OrElse(current, match) : match)); + + private static void InsertOnDuplicateKeyUpdate(DbContext dbContext, IEnumerable seed) where TEntity : IBaseEntity { - var values = CreateValues(seedRows, properties); + var entityType = dbContext.Model.FindEntityType(typeof(TEntity)); + var properties = GetPropertiesLessValueGeneratedTimestamps(entityType); + var values = CreateValues(seed, properties); if (values == "") return; var columns = string.Join(", ", properties.Select(x => x.Name)); @@ -95,10 +100,15 @@ private static void InsertOnDuplicateKeyUpdate(DbContext dbContext, dbContext.Database.ExecuteSqlCommand(sql); } - private static string CreateValues(IEnumerable seedRows, + private static List GetPropertiesLessValueGeneratedTimestamps(IEntityType entityType) => + entityType.GetProperties() + .Where(x => !new List {"CreatedDateUtc", "ModifiedDateUtc"}.Contains(x.Name)) + .ToList(); + + private static string CreateValues(IEnumerable seed, IReadOnlyCollection properties) where TEntity : IBaseEntity => - seedRows.Select(row => CreateRowValues(properties, row)) - .Aggregate("", (current, rowValues) => current == "" ? rowValues : current + ", " + rowValues); + seed.Select(row => CreateRowValues(properties, row)) + .Aggregate("", (current, rowValues) => current == "" ? rowValues : current + ", " + rowValues); private static string CreateRowValues(IEnumerable properties, TEntity row) where TEntity : IBaseEntity =>