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>Id
s. 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