[英]EF Core 1.1 Soft (or logical) Delete
I'm trying to implement Soft Delete in a .NET Core 1.1.* Web App, backed by Entity Framework Core 1.1.*. 我正在尝试在由Entity Framework Core 1.1。*支持的.NET Core 1.1。* Web App中实现软删除。 I'm using Sql Server as my DB.
我正在使用Sql Server作为数据库。
Migrating to .NET core 2.* is not an option at the moment. 目前尚不能迁移到.NET core 2. *。
After reading books, tuts and 3ds, I've implemented this feature using a Discriminator
column. 在阅读书籍,教程和3ds之后,我已经使用
Discriminator
列实现了此功能。 The deletion procedure is apparently working as expected. 删除过程显然按预期方式工作。 What's wrong is the data retrieval: deleted entities are still shown within my EF query results.
数据检索出了问题:已删除的实体仍显示在我的EF查询结果中。
Here's some C# code. 这是一些C#代码。 I'll keep things as simple as possible
我会尽量简化
The interfaces: 接口:
// Soft deletion interface
public intercace ISoftDeletable
{}
// Another interface for some shadow properties
public interface IEntity
{}
The base class: 基类:
public abstract class Entity : IEntity, ISoftDeletable
{
public int MyBaseProp { get; set; }
}
One of my derived classes: 我的派生类之一:
public class MyDerivedEntity: Entity
{
public string Name { get; set; }
public IList<MyChildEntity> Children { get; set; }
}
public class MyChildEntity: Entity
{
public string MyChildProp { get; set; }
}
The Context 上下文
public class MyContext: DbContext
{
public MyContext(DbContextOptions<MyContext> options)
: base(options)
{ }
public DbSet<MyDerivedEntity> EntitiesToUse { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
foreach (var entity in builder.Model.GetEntityTypes())
{
if (typeof(IEntity).IsAssignableFrom(entity.ClrType))
{
builder.Entity(entity.ClrType).Property<string>("MyShadowProperty");
}
if (typeof(ISoftDeletable).IsAssignableFrom(entity.ClrType))
{
// Discriminator column
builder.Entity(entity.ClrType).HasDiscriminator("IsDeleted", typeof(bool)).HasValue(false);
// Shadow Property
builder.Entity(entity.ClrType).Property(typeof(bool), "IsDeleted").IsRequired(true).HasDefaultValue(false);
builder.Entity(entity.ClrType).Property(typeof(bool), "IsDeleted").Metadata.IsReadOnlyAfterSave = false;
}
}
// Other model configurations
base.OnModelCreating(builder);
}
// SaveChangesAsync are almost the same
public override int SaveChanges()
{
AuditEntities();
return base.SaveChanges();
}
private void AuditEntities()
{
foreach (EntityEntry<IEntity> entry in ChangeTracker.Entries<IEntity>())
{
// do something with MyShadowProperty...
}
foreach (EntityEntry<ISoftDeletable> entry in changeTracker.Entries<ISoftDeletable>().Where(w => w.State == EntityState.Deleted))
{
// Set the entity as Softly Deleted
entry.Property("IsDeleted").CurrentValue = true;
// Ensure the entity state is modified to prevend hard deletion
entry.State = EntityState.Modified;
}
}
}
Everything works as expected, except the data retrieval. 除数据检索外,其他所有操作均按预期进行。 Here's a sample call:
这是一个示例调用:
var results = await _context.EntitiesToUse.Include(e => e.SomeChildEntity).AsNoTracking();
I expect the results to include only available myDerivedEntities with .IsDeleted == false
. 我希望结果仅包含具有
.IsDeleted == false
可用 myDerivedEntities。 The problem is that my deleted entities are not filtered out. 问题是我的删除实体没有被过滤掉。 Why?
为什么?
Please, what's wrong with my code? 拜托,我的代码怎么了? Am I missing something?
我想念什么吗?
Thank you all so much! 非常感谢大家!
Entity Framework Core 2.0 supports Global Query Filter 实体框架核心2.0支持全局查询过滤器
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ISoftDeletable>().HasQueryFilter(e => !e.IsDeleted);
base.OnModelCreating(modelBuilder);
}
You can find more info and examples here 您可以在此处找到更多信息和示例
I recommend you the built-in EF Core Global Query Filter but in some situations, Entity Framework Plus could also help. 我建议您使用内置的EF Core全局查询过滤器,但在某些情况下, Entity Framework Plus也可以提供帮助。
Disclaimer : I'm the owner of this project 免责声明 :我是该项目的所有者
EF+ Query Filter allows you to filter DbSet Globally and by Instance. EF +查询过滤器允许您全局和按实例过滤DbSet。
// using Z.EntityFramework.Plus; // Don't forget to include this.
var ctx = new EntitiesContext();
ctx.Filter<IUser>(q => q.Where(x => !x.IsSystemUser ));
// SELECT * FROM Customers WHERE IsSystemUser = FALSE
var list = ctx.Customers.ToList();
Wiki: EF+ Query Filter Wiki: EF +查询过滤器
EDIT: Answer sub-question 编辑:回答子问题
Please, Is your library compatible with EF Core 1.1
请,您的库是否与EF Core 1.1兼容
Yes, it should be compatible with .NET Standard 1.3 是的,它应该与.NET Standard 1.3兼容
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.