c# - 检测 MongoDb 数据库是否将被创建/已创建

标签 c# mongodb

我们为每个租户使用一个数据库。所以我们的代码如下所示:

 var collection = MongoClient.GetDatabase(accountId).GetCollection("mycol");

我们不知道此时数据库是否已经存在。集合也一样。

问题:我想创建一个索引。为了能够做到这一点,我需要在创建新数据库或集合时有一些“事件”,所以我知道我必须为其创建索引。

选项:

  • 如果 GetDatabase() 或 GetCollection() 调用有机会出现错误/异常/null,我可以处理此问题并“准备”数据库/集合。问题:没有错误或任何允许我检查它是否是新的/不存在的内容?
  • 驱动程序事件:我看到驱动程序 ( http://mongodb.github.io/mongo-csharp-driver/2.6/reference/driver_core/events/ ) 中有事件,但那似乎是错误的地方?
  • 更改事件:https://docs.mongodb.com/manual/changeStreams/看起来还不错,有一个 dropDatabase 事件 - 但没有 createDatabase 事件。
  • 在插入/更新之前手动检查。这将需要向数据库发出额外的请求。坏主意……
  • ???

创建数据库或集合时有什么方法可以获取触发器吗?

最佳答案

MongoDB 和其他类似 RDBMS 的数据库之间的主要区别在于,MongoDB 中的数据库和集合是自动创建的。文档说:

If a database does not exist, MongoDB creates the database when you first store data for that database

因此,当您尝试访问不存在的数据库时,您不会收到任何错误。更重要的是,C# 驱动程序中没有“DatabaseExists”方法,但您可以创建自己的方法。要检查数据库是否存在,您可以使用 db.stats管理命令返回有关特定数据库的一些重要统计信息。

db.stats 的示例结果可能如下所示:

{
    "db" : "databasene2",
    "collections" : 0,
    "views" : 0,
    "objects" : 0,
    "avgObjSize" : 0,
    "dataSize" : 0,
    "storageSize" : 0,
    "numExtents" : 0,
    "indexes" : 0,
    "indexSize" : 0,
    "fileSize" : 0,
    "fsUsedSize" : 0,
    "fsTotalSize" : 0,
    "ok" : 1
}

因此,您可以在 C# 中创建一个扩展方法,如果没有集合和索引,该方法将返回 null:

public static IMongoDatabase GetDatabaseIfExists(this IMongoClient client, string databaseName)
{
    var database = client.GetDatabase(databaseName);
    var command = "{ dbStats: 1, scale: 1 }";
    var dbStats = database.RunCommand<BsonDocument>(command);
    var databaseExists = dbStats["collections"].AsInt32 > 0 || dbStats["indexes"].AsInt32 > 0;

    return databaseExists ? database : null;
}

用法:

var mongoClient = new MongoClient(settings);
var db = mongoClient.GetDatabaseIfExists("dbThatNotExists"); //returns null

同样,您可以利用 collStats 创建另一种方法命令,MongoDB C# 驱动程序在这种情况下抛出 MongoCommandException,请尝试:

public static IMongoCollection<T> GetCollectionIfExists<T>(this IMongoDatabase database, string collectionName)
{
    var command = $"{{ collStats: \"{collectionName}\", scale: 1 }}";
    try
    {
        database.RunCommand<BsonDocument>(command);
        return database.GetCollection<T>(collectionName);
    }
    catch(MongoCommandException e) when (e.ErrorMessage.EndsWith("not found."))
    {
        return null;
    }
}

显然,您不必每次需要访问数据库时都运行这些方法。您可以运行它们一次,然后将现有数据库名称缓存在内存中并直接使用 GetDatabase

关于c# - 检测 MongoDb 数据库是否将被创建/已创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53656461/

相关文章:

c# - 将多个枚举传递给方法并获取它们的值

mongodb - 如何更改 MongoDB mapreduce 结果的结构?

javascript - Node.JS 中 child_process 的 execFile 中的异步函数

c# - 如何改进 Entity Framework 和 Javascript 交互

c# - .NET XML : What is the . NET 相当于 XmlDocument.TransformNode?

c# - 如何从 C# System.Windows.Form.HtmlElement 中提取 *immediate* 文本(即不是子文本)

javascript - Nodejs异步mongodb保存或更新

mongodb - pymongo cursor getMore 需要很长时间

php - 有一系列问题,我需要检查用户是否在每个问题中投票了任何答案

c# - Python 女服务员 API 挂起