C# 如何检查与mongodb的连接

C# 如何检查与mongodb的连接,c#,mongodb,C#,Mongodb,我使用MongoDB驱动程序连接到数据库。当我的表单加载时,我想建立连接并检查它是否正常。我是这样做的: var connectionString = "mongodb://localhost"; var client = new MongoClient(connectionString); var server = client.GetServer(); var database = server.GetDatabase("reestr"); 但我不知道如何检查连接。我试图将此代码与try

我使用
MongoDB
驱动程序连接到数据库。当我的表单加载时,我想建立连接并检查它是否正常。我是这样做的:

var connectionString = "mongodb://localhost";
var client = new MongoClient(connectionString);
var server = client.GetServer();
var database = server.GetDatabase("reestr");
但我不知道如何检查连接。我试图将此代码与
try catch
重叠,但没有成功。即使我的连接字符串不正确,我仍然无法获得任何错误消息。

有一个解决方案:

var connectionString = "mongodb://localhost";
var client = new MongoClient(connectionString);
var server = client.GetServer();
server.Ping();

要使用新的3.0驱动程序ping服务器,请执行以下操作:

var database = client.GetDatabase("YourDbHere");

database.RunCommandAsync((Command<BsonDocument>)"{ping:1}")
        .Wait();
var-database=client.GetDatabase(“yourdwhere”);
database.RunCommandAsync((命令)“{ping:1}”)
.Wait();

如果要处理程序中的连接问题,可以使用事件

创建时,它将继续在后台尝试连接,直到成功

using MongoDB.Driver;
using MongoDB.Driver.Core.Clusters;

var mongoClient = new MongoClient("localhost")
mongoClient.Cluster.DescriptionChanged += Cluster_DescriptionChanged;

public void Cluster_DescriptionChanged(object sender, ClusterDescriptionChangedEventArgs e)
{
    switch (e.NewClusterDescription.State)
    {
        case ClusterState.Disconnected:
            break;
        case ClusterState.Connected:
            break;
    }
}

2.4.3的完整示例-其中“client.GetServer()”不可用。 基于“保罗·凯斯特”的回答

client=新的MongoClient(“mongodb://localhost");
database=client.GetDatabase(mongoDbStr);
bool ismonglive=database.RunCommandAsync((命令){ping:1}”).Wait(1000);
如果(伊斯蒙奥利夫)
{
//连接的
}
其他的
{
//无法连接
}

我遇到了与OP相同的问题,并尝试了在互联网上找到的每一个解决方案。。。 好吧,没有一个能让我真正满意,所以我选择了一项研究,以找到一种可靠且响应迅速的方法来检查与MongoDB数据库服务器的连接是否有效。这不会阻止应用程序的同步执行太长时间

以下是我的先决条件:

  • 连接检查的同步处理
  • 用于连接检查的短到极短时间片
  • 连接检查的可靠性
  • 如果可能,不要抛出异常和触发超时
我在默认的本地主机URL上提供了一个新的MongoDB安装(版本3.6):mongodb://localhost:27017。我还写了另一个URL,其中没有MongoDB数据库服务器:mongodb://localhost:27071

我还使用C#Driver 2.4.4,不使用遗留实现(MongoDB.Driver.legacy assembly)

所以我的期望是,当我检查到第一个URL的连接时,它应该给我一个到现有MongoDB服务器的活动连接的Ok,当我检查到第二个URL的连接时,它应该给我一个不存在的MongoDB服务器的Fail

使用IMongoDatabase.RunCommand方法,查询服务器并导致服务器响应超时,因此不符合先决条件。此外,在超时之后,它会因TimeoutException而中断,这需要额外的异常处理

这个实际的SO问题和同样的SO问题提供了我解决方案所需的大部分启动信息。。。伙计们,非常感谢

现在我的解决方案是:

    private static bool ProbeForMongoDbConnection(string connectionString, string dbName)
    {
        var probeTask = 
                Task.Run(() =>
                            {
                                var isAlive = false;
                                var client = new MongoDB.Driver.MongoClient(connectionString);

                                for (var k = 0; k < 6; k++)
                                {
                                    client.GetDatabase(dbName);
                                    var server = client.Cluster.Description.Servers.FirstOrDefault();
                                    isAlive = (server != null && 
                                               server.HeartbeatException == null && 
                                               server.State == MongoDB.Driver.Core.Servers.ServerState.Connected);
                                    if (isAlive)
                                    {
                                        break;
                                    }
                                    System.Threading.Thread.Sleep(300);
                                }
                                return isAlive;
                            });
        probeTask.Wait();
        return probeTask.Result;
    }
将打印出来

连接到mongodb://localhost:27017 成功了

和语句(用于无效URL)

将打印出来

连接到mongodb://localhost:27071 没有成功


这里是ping mongodb服务器的一个简单扩展方法

public static class MongoDbExt
{
    public static bool Ping(this IMongoDatabase db, int secondToWait = 1)
    {
        if (secondToWait <= 0)
            throw new ArgumentOutOfRangeException("secondToWait", secondToWait, "Must be at least 1 second");

        return db.RunCommandAsync((Command<MongoDB.Bson.BsonDocument>)"{ping:1}").Wait(secondToWait * 1000);
    }
} 

这是一种使用try-catch方法的解决方案

var database = client.GetDatabase("YourDbHere");
bool isMongoConnected;
try
{
     await database.RunCommandAsync((Command<BsonDocument>)"{ping:1}");
     isMongoConnected = true;
}
catch(Exception)
{
    isMongoConnected = false;
}    
var-database=client.GetDatabase(“yourdwhere”);
布尔是连接的;
尝试
{
wait database.RunCommandAsync((命令){ping:1});
isMongoConnected=true;
}
捕获(例外)
{
isMongoConnected=错误;
}    


因此,当它无法连接到数据库时,它将抛出一个异常,我们可以在那里处理bool标志。

关于这一点的API文档很弱,非常弱,但通常一个众所周知的协议是,当您无法执行诸如GetServer或GetDatabase之类的操作时抛出异常。我会尝试捕捉这些语句,除非您看到异常,否则请继续。例外情况会告诉你你需要知道的,就是这样。但是问题是,
try-catch
在这种情况下没有帮助。坦白说,
try-catch
有帮助,但只是部分帮助。此连接字符串“mongo://localhost导致一个错误,但这mongodb://123“-not.private静态bool CheckConnection(){var url=new MongoUrl(”mongodb://123“”;var client=new MongoClient(url);var server=client.GetServer();var database=server.GetDatabase(“test”);尝试{database.GetStats()}catch(MongoConnectionException){return false;}return true;}如何使用新的Mongo DB C#2.0驱动程序?是的,知道如何使用新的3.0驱动程序检查连接状态吗?它没有服务器对象。现在已弃用。新方法似乎是
MongoDB.Driver.Core.Operations.PingOperation
@MaxBarraclough:注意语义可能已经改变,因为4.0驱动程序现在知道重试,所以显式检查集群中某个服务器的连接似乎没有意义。尝试该操作,让驱动程序处理重试操作,并且只担心操作失败的情况。Ping似乎是与集群对话时的一个低级工具。你的答案与Paul Keister的答案有何不同?Paul的答案不清楚你对请求做了什么。他指出了正确的方向,但没有完整地回答问题。这对一个傻瓜来说更有意义:)我用这个得到了错误的否定。你的联系有多可靠?增加等待?这是异步的,有同步方式吗?从2.0开始,驱动程序仅为异步。很抱歉吹毛求疵,但我的示例实际上是同步的,因为我调用的
Wait()
似乎总是返回false,即使一切正常。这是可行的,但这个实现的问题是需要DB名称,我希望得到类似IsAlive的Mongo连接字符串方法(也可以是副本集)如果不需要获取数据库名称,则此操作不起作用
// The admin database should exist on each MongoDB 3.6 Installation, if not explicitly deleted!
isAlive = ProbeForMongoDbConnection("mongodb://localhost:27071", "admin");
Console.WriteLine("Connection to mongodb://localhost:27071 was " + (isAlive ? "successful!" : "NOT successful!"));
public static class MongoDbExt
{
    public static bool Ping(this IMongoDatabase db, int secondToWait = 1)
    {
        if (secondToWait <= 0)
            throw new ArgumentOutOfRangeException("secondToWait", secondToWait, "Must be at least 1 second");

        return db.RunCommandAsync((Command<MongoDB.Bson.BsonDocument>)"{ping:1}").Wait(secondToWait * 1000);
    }
} 
var client = new MongoClient("yourConnectionString");
var database = client.GetDatabase("yourDatabase");
if (!database.Ping())
    throw new Exception("Could not connect to MongoDb");
var database = client.GetDatabase("YourDbHere");
bool isMongoConnected;
try
{
     await database.RunCommandAsync((Command<BsonDocument>)"{ping:1}");
     isMongoConnected = true;
}
catch(Exception)
{
    isMongoConnected = false;
}