Я пытаюсь расширить мою пользовательскую подпрограмму (я знаю, что EF Core 2.1 изначально поддерживает заполнение, но у меня есть блокировщик в преобразовании) для применения удалений.Если запись существует в базе данных, но больше не существует в начальных данных, я хочу удалить ее.Вместо того чтобы писать собственную процедуру удаления для каждого DbSet
, я пытаюсь реализовать ее с помощью обобщений (и, возможно, отражения при необходимости).
Моя первая попытка:
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();
}
Однако, посколькуTEntity
содержит некоторые свойства, которые являются нулевыми в начальных данных (например, временные метки, сгенерированные при добавлении), я не могу сравнить целые сущности в вызове Except()
(в любом случае со средством сравнения равенства по умолчанию).Я действительно беспокоюсь только о сравнении первичного ключа.
Моя работа над решением этой проблемы приведена ниже.TEntity
может иметь первичный ключ простого столбца Id
или это может быть сопоставление «многие ко многим» со сложным первичным ключом, равным двум <EntityName>Id
с.IBaseEntity
в настоящее время не имеет никакой информации Id
/ первичного ключа, поскольку она реализуется как базовыми объектами, так и объектами "многие ко многим / соединениям".
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();
}
полный источник /context
Однако два экземпляра .Select(s => idProperties)
, очевидно, не работают.Есть ли способ выбрать свойства Id
(или, альтернативно, первичный ключ) для DbSet<T>
для использования в компараторе Except()
?Я также открыт для совершенно другого подхода, так как я чувствую, что я в сорняках.