gpt4 book ai didi

c# - 通用存储库模式软删除

转载 作者:行者123 更新时间:2023-12-02 01:35:39 24 4
gpt4 key购买 nike

我创建了一个通用存储库(使用 EF 6.1.1),我在多个项目中使用它,并且运行良好。我实现了“软”删除功能,我们将数据标记为已删除,但实际上并不将其从数据库中删除。

然后,我可以过滤所有查询,因为所有实体都继承自具有 IsDeleted 属性的基本实体。这一切都很好,但它显然没有过滤掉任何“软删除”的子实体。

我不确定如何以通用方式执行此操作,因为我不想将解决方案过度编码到每个存储库中,这确实违背了拥有通用存储库的原因。

这是我当前通用存储库的示例

public sealed class MyRepository<T> : IRepository<T> where T : BaseEntity
{
public String CurrentUser { get; set; }
private readonly MyObjectContext context;

private readonly Configuration configuration = ConfigurationManager.GetConfiguration();
private IDbSet<T> entities;
private IDbSet<T> Entities
{
get { return entities ?? (entities = context.Set<T>()); }
}

public MyRepository(MyObjectContext context, String userName = null)
{
this.context = context;

var providerManager = new DataProviderManager(configuration);
var dataProvider = (IDataProvider)providerManager.LoadDataProvider();
dataProvider.InitDatabase();

CurrentUser = userName;
}

public void Dispose()
{
//do nothing at the moment
}

public T GetById(Guid id)
{
return Entities.FirstOrDefault(x => x.Id == id && !x.IsDeleted);
}

public IQueryable<T> GetAll()
{
return Entities.Where(x => !x.IsDeleted);
}

public IQueryable<T> Query(Expression<Func<T, bool>> filter)
{
return Entities.Where(filter).Where(x => !x.IsDeleted);
}

public void Delete(T entity)
{
if (configuration.HardDelete)
{
HardDelete(entity);
}
else
{
SoftDelete(entity);
}
}

private void HardDelete(T entity)
{

try
{
if (entity == null)
{
throw new ArgumentNullException("entity");
}
Entities.Attach(entity);
Entities.Remove(entity);

}
catch (DbEntityValidationException ex)
{
var msg = string.Empty;

foreach (var validationErrors in ex.EntityValidationErrors)
foreach (var validationError in validationErrors.ValidationErrors)
msg += Environment.NewLine + string.Format("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);

var fail = new Exception(msg, ex);
throw fail;
}
}

private void SoftDelete(T entity)
{
entity.IsDeleted = true;
Update(entity);
}
}

对此的任何帮助都会很棒。

谢谢

最佳答案

有人构建了一个全局过滤器,您可以尝试并从 nuget EntityFramework.Filters 安装它。

https://github.com/jbogard/EntityFramework.Filters

这是一个如何使用它的示例。

public abstract class BaseEntity
{
public int Id { get; set; }
public bool IsDeleted { get; set; }
}
public class Foo : BaseEntity
{
public string Name { get; set; }
public ICollection<Bar> Bars { get; set; }
}
public class Bar : BaseEntity
{
public string Name { get; set; }
public int FooId { get; set; }
public Foo Foo { get; set; }
}
public class AppContext : DbContext
{
public DbSet<Foo> Foos { get; set; }
public DbSet<Bar> Bars { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Registers and configures it first.
DbInterception.Add(new FilterInterceptor());
var softDeleteFilter = FilterConvention.Create<BaseEntity>("SoftDelete",
e => e.IsDeleted == false); // don't change it into e => !e.IsDeleted
modelBuilder.Conventions.Add(softDeleteFilter);
}
}

然后您可以在存储库构造函数中或创建数据库上下文实例后的某个位置启用它,因为默认情况下禁用过滤器。

using (var db = new AppContext())
{
db.EnableFilter("SoftDelete");
var foos = db.Foos.Include(f => f.Bars).ToArray(); // works on Include
}
using (var db = new AppContext())
{
db.EnableFilter("SoftDelete");
var foos = db.Foos.ToArray();
foreach (var foo in foos)
{
var bars = foo.Bars; // works on lazy loading
}
}
using (var db = new AppContext())
{
db.EnableFilter("SoftDelete");
var foos = db.Foos.ToArray();
foreach (var foo in foos)
{
db.Entry(foo).Collection(f => f.Bars).Load(); // works on manual loading
}
}

不再需要此过滤器。

public IQueryable<T> Query(Expression<Func<T, bool>> filter)
{
return Entities.Where(filter);//.Where(x => !x.IsDeleted);
}

只要您启用了它。

public MyRepository(MyObjectContext context, String userName = null)
{
this.context = context;

if (!configuration.HardDelete)
{
this.context.EnableFilter("SoftDelete");
}
}

关于c# - 通用存储库模式软删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24534615/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com