You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中通过MongoDb.Driver实现软删除全局过滤(无需EF)

在MongoDB Driver中实现软删除全局过滤(无需EntityFramework)

当然可以实现,以下是两种靠谱的方案,直接基于MongoDB Driver完成全局软删除过滤:

方案一:使用MongoDB Driver全局过滤器(推荐,Driver 2.10+支持)

通过配置MongoClient的全局过滤器,对所有实现ISoftDelete接口的实体自动添加过滤条件,无需在每次查询时手动处理。

实现步骤:

  1. 确保你的ISoftDelete接口定义正确:
public interface ISoftDelete
{
    bool IsDeleted { get; set; }
}
  1. 在初始化IMongoClient时,配置全局过滤器:
var settings = MongoClientSettings.FromConnectionString("你的MongoDB连接字符串");

settings.ClusterConfigurator = builder =>
{
    builder.Subscribe<CommandStartedEvent>(e =>
    {
        // 只针对查询类命令添加过滤
        if (e.CommandName == "find" || e.CommandName == "aggregate")
        {
            // 根据集合名获取对应的实体类型,你需要自己维护集合名与实体类型的映射逻辑
            var entityType = GetEntityTypeByCollectionName(e.Command["find"].AsString);
            
            if (typeof(ISoftDelete).IsAssignableFrom(entityType))
            {
                // 构造过滤条件:IsDeleted = false
                var filter = BsonDocument.Parse("{ IsDeleted: false }");
                
                // 将过滤条件合并到原查询中
                if (e.Command.Contains("filter"))
                {
                    var existingFilter = e.Command["filter"].AsBsonDocument;
                    e.Command["filter"] = new BsonDocument("$and", new BsonArray { existingFilter, filter });
                }
                else
                {
                    e.Command.Add("filter", filter);
                }
            }
        }
    });
};

var client = new MongoClient(settings);

方案二:自定义集合扩展方法(更灵活可控)

如果不想用全局过滤器,也可以封装一个扩展方法,每次获取集合时自动应用软删除过滤,统一管理查询逻辑。

实现代码:

public static class MongoCollectionExtensions
{
    public static IMongoCollection<T> GetSoftDeleteCollection<T>(this IMongoDatabase database, string collectionName = null)
    {
        var collection = string.IsNullOrEmpty(collectionName) 
            ? database.GetCollection<T>() 
            : database.GetCollection<T>(collectionName);

        // 如果当前实体实现了ISoftDelete,返回带过滤的集合
        if (typeof(ISoftDelete).IsAssignableFrom(typeof(T)))
        {
            var filter = Builders<T>.Filter.Eq(nameof(ISoftDelete.IsDeleted), false);
            return collection.WithFilter(filter);
        }

        return collection;
    }
}

使用方式:

// 获取应用了软删除过滤的集合
var usersCollection = database.GetSoftDeleteCollection<User>(); // User实现了ISoftDelete

// 普通查询自动排除已删除记录
var activeUsers = await usersCollection.Find(Builders<User>.Filter.Empty).ToListAsync();

// 如果需要查询已删除记录,手动构造包含IsDeleted=true的过滤器
var deletedUsers = await usersCollection.Find(Builders<User>.Filter.Eq(u => u.IsDeleted, true)).ToListAsync();

注意事项

  • 执行批量更新/删除操作时,优先设置IsDeleted字段标记软删除,而非真正删除文档。
  • 全局过滤器会作用于所有符合条件的查询命令,包括聚合查询;若需包含已删除记录,可手动在查询中添加IsDeleted: true的条件覆盖默认过滤。

内容的提问来源于stack exchange,提问作者Rick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 14:37:39