ORMLite / ServiceStack 软删除

ORMLite / ServiceStack soft deletes

好的,我已经就此发布了几次,但仍未在这里找到有效的解决方案。我看过其他示例/建议并遵循了它们,但没有成功。我已经筋疲力尽了,希望能在这里弄清楚。最终,我试图实现 select 数据库中任何对象的能力,同时过滤 'IsDeleted' 标志。

我将 ORMLite 与 ServiceStack 一起使用。我使用的是存储库模式,还使用了带有 ServiceStack 的 Funq。当我的 AppHost 启动时,我在容器中注册我的 DbConnectionFactory 以及我的存储库实例。连接工厂通过构造函数注入传递。

public override void Configure(Container container)
{
    <...>

    container.Register<IDbConnectionFactory>(new OrmLiteConnectionFactory(ConfigurationManager.ConnectionStrings["connstring"].ConnectionString, SqlServerDialect.Provider));
    container.Register<ICompanyRepository>(c => new Repositories.OrmLite.CompanyRepository(container.Resolve<IDbConnectionFactory>()));

    <...>
}

我的所有模型 classes 都有一个共同的基础 class / 接口,其中包含我们的标准审计字段以及 'IsDeleted' 标志。这由名为 'IAuditModel':

的接口表示
public interface IAuditModel
{
    int CreatedBy { get; set; }
    int ModifiedBy { get; set; }
    DateTime CreatedDateTime { get; set; }
    DateTime ModifiedDateTime { get; set; }
    bool IsModified { get; set; }
}

在我的存储库 class 中,我试图检索未标记为已删除的记录,但我试图避免在每次查询时都必须指定它。我已经尝试通过在基本存储库 class:

的构造函数中为类型创建一个特定的 select 过滤器
public class OrmLiteRepositoryBase : IRepositoryBase
{
    <...>

    protected readonly OrmLiteConnectionFactory olcf;

    public OrmLiteRepositoryBase(IDbConnectionFactory cf)
    {
        olcf = cf as OrmLiteConnectionFactory;

        SqlExpression<Vendor>.SelectFilter = q => q.Where(x => !x.IsDeleted);

        OrmLiteConfig.InsertFilter = (dbCmd, row) =>
        {
            <...>
        }

        OrmLiteConfig.UpdateFilter = (dbCmd, row) =>
        {
            <...>
        }

        <...>
    }
}

供应商 class 通过基础 class 实现 IAuditModel。以上是我第一次尝试过滤特定类型。然后我尝试了下面的方法,遵循我在 Whosebug here 以及 github 上的 SoftDeleteUseCase 中找到的建议:

OrmLiteConfig.SqlExpressionSelectFilter = (q) =>
{
    if(q.ModelDef.ModelType.HasInterface(typeof(IAuditModel))
    {
        a.Where<IAuditModel>(x => x.IsDeleted);
    }
}

我已尝试在以下内容中包含此 select 过滤器:

  1. 在应用程序主机中,注册连接工厂后。
  2. 在存储库构造函数中,InsertFilter 所在的位置。
  3. 在存储库方法本身中,打开 DbConnection 之后。

我最终在共享库 class 中使用通用方法进行查询,如下所示:

db.Select<T>();

没有任何效果,我每次都取回所有记录(包括标记为 'deleted' 的记录)。有趣的是,如上所示,存储库构造函数中的 InsertFilter 和 UpdateFilter 工作如我所料。我这辈子都无法让这个 select 过滤器发挥作用。在调用 'Select()' 之后调用 'GetLastSql()' 显示没有应用过滤器的迹象。任何人,任何人,请帮助我理解这一点。谢谢。

软删除过滤器将条件附加到 SqlExpression,因此在其实现中附加到 only applies to APIs that use an SqlExpression,例如:

var results = db.Select(db.From<Table>());
var result = db.Single(db.From<Table>().Where(x => x.Name == "foo"));
var result = db.Single(x => x.Name == "foo");