lundi 10 septembre 2018

Apply deletes during custom seed of DbSet

I am trying to extend my custom seed routine (I know EF Core 2.1 supports seeding natively, but I have a blocker in converting) to apply deletions. If a record exists in the database, but no longer in the seed data, I want to delete it. Rather than writing a custom delete routine for each DbSet, I am trying to implement with generics (and possibly reflection if needed).

My first attempt:

private static void Delete<TEntity>(DbContext dbContext, IEnumerable<TEntity> seedRows) where TEntity : class, IBaseEntity
{
    var toRemove = dbContext.Set<TEntity>().Except(seedRows);
    dbContext.RemoveRange(toRemove);
    dbContext.SaveChanges();
}

However, since TEntity contains some properties that are null in the seed data (such as timestamps generated on add), I can't compare the entire entities in the Except() call (with the default equality comparer, anyway).

My work in progress for addressing this issue is below. TEntity could have a primary key of a simple Id column, or it could be a many-to-many mapping with a complex primary key of two <EntityName>Ids. IBaseEntity currently does not have any Id/primary key information since it is implemented both by basic entities as well as many-to-many/junction entities.

private static void Delete<TEntity>(DbContext dbContext, IEnumerable<TEntity> seedRows) where TEntity : class, IBaseEntity
{
    var idProperties = typeof(TEntity).GetProperties().Where(p => p.Name.Contains("Id"));
    var toRemove = dbContext.Set<TEntity>().Select(s => idProperties).Except(seedRows.Select(s => idProperties));
    dbContext.RemoveRange(toRemove);
    dbContext.SaveChanges();
}

The two instances of .Select(s => idProperties), however, obviously do not work. Is there a way to select the Id properties (or, alternatively, the primary key) of a DbSet<T> to be used in Except() comparer? I am open to a completely different approach as well, since I feel like I am off in the weeds.





Aucun commentaire:

Enregistrer un commentaire