ASP.NET 和 Neo4jClient - 在哪里存储连接?

Posted

技术标签:

【中文标题】ASP.NET 和 Neo4jClient - 在哪里存储连接?【英文标题】:ASP.NET and Neo4jClient - where to store the connection? 【发布时间】:2014-03-28 02:35:11 【问题描述】:

C# Neo4JClient 有GraphClient,您必须在其中调用.Connect()

var client = new GraphClient(new Uri("http://localhost:7474/db/data"));
client.Connect();

在我看到的所有示例中,它都在控制台应用程序中,因此他们在 Main() 中声明 GraphClient 并重新使用它。并且文档提到了它的线程安全以及每个数据库只有一个实例并且不多次调用.Connect()

但是在 ASP.NET 应用程序中呢?我应该将它粘贴在页面访问的某个静态类中(或将其存储在应用程序状态中)吗?像这样:

public class DbConnection

    private static GraphClient _client;
    public static GraphClient GraphClient
    
        get
        
            if (_client == null)
            
                _client = new GraphClient(new Uri("http://localhost:7474/db/data"));
                _client.Connect();
            
            return _client;
        
    

然后我可以在任何 ASPX 页面中简单地:

protected void Page_Load(object sender, EventArgs e)

    GraphClient client = DbConnection.GraphClient;
    //do whatever I need to with client

还是我理解不正确,会导致各种问题?我是否需要在每个方法中调用.Connect()(或者每个页面生命周期一次),如下所示:

private GraphClient _client;
private GraphClient PageGraphClient

    get  //same as in previous, check if null and load _client with the connection 


protected void Page_Load(object sender, EventArgs e)

    //do whatever I need to with PageGraphClient


protected void btnSave_Click(object sender, EventArgs e)

    //do whatever I need to with PageGraphClient

等等?我想我只是被整个线程安全的事情和“与数据库建立太多连接”并想确保我不会错过一个简单/正确的方法来做到这一点。

(是的,我知道我不应该直接从 ASPX 页面调用数据库命令,为了理解 GraphClient 类的工作原理,我过于简化了;)

【问题讨论】:

您对依赖注入有何感受?你以前做过 - 你用起来舒服吗? @chris-skardon 我以前不需要这样做,但如果方法正确,我愿意学习新东西? OK - 这是一个 ASP.NET aspx 项目,还是一个 MVC 项目? @ChrisSkardon 这是一个 MVC 项目。 2018年的回复:官方驱动页面还没有解释这个 【参考方案1】:

使用 Ninject(DI 框架)设置您的项目:

为您的 MVC 版本(即 Ninject.MVC5 等)添加 Ninject.MVC nuget 包 添加 Neo4jClient 包(虽然我想你已经有了这个) 连接 Ninject,让它知道 IGraphClient 是什么

我为此使用了一个模块,所以将这个类添加到您的项目中(通常我将它们放在 App_Start 文件夹中名为“Modules”的子文件夹中 - 但它可以在任何地方):

public class Neo4jModule : NinjectModule

    /// <summary>Loads the module into the kernel.</summary>
    public override void Load()
    
        Bind<IGraphClient>().ToMethod(InitNeo4JClient).InSingletonScope();
    

    private static IGraphClient InitNeo4JClient(IContext context)
    
        var neo4JUri = new Uri(ConfigurationManager.ConnectionStrings["Neo4j"].ConnectionString);
        var graphClient = new GraphClient(neo4JUri);
        graphClient.Connect();

        return graphClient;
    

我们已将 GraphClient 加载到单例范围内,您可以在此处阅读所有相关信息:Object Scopes

现在我们只需要告诉 Ninject 加载模块,因此在 NinjectWebCommon.cs 文件(在 App_Start 文件夹中)编辑 RegisterServices 方法(在文件底部),使其看起来像:

/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)

    kernel.Load<Neo4jModule>();
 
注入控制器

这是添加构造函数(或修改现有构造函数)以获取IGraphClient 实例的情况:

private readonly IGraphClient _graphClient;
public HomeController(IGraphClient graphClient)

    _graphClient = graphClient;

现在控制器有一个GraphClient 的实例,可以随意使用:

public ActionResult Index()

    ViewBag.NodeCount =  _graphClient.Cypher.Match("n").Return(n => n.Count()).Results.Single();

    return View();

显然,扩展它,您可以添加一个基础 Neo4jController,任何需要 Neo4j 的控制器都会覆盖它。

【讨论】:

好的,很酷,很有意义,谢谢!我将阅读所有这些内容,但我留下的一个问题更多地只是为了我自己的教育,那就是:这是在应用程序的生命周期内保持 Neo4jClient 连接打开,还是对控制器的每个请求行动,或者它是如何工作的?我只是好奇。 “对象范围”的链接将帮助您,但有四个选项,瞬态 - 每次请求时创建新实例,单例 - 每次请求仅创建并返回单个实例, Thread - 每个线程一个实例,Request - 每个 Web 请求一个实例,在请求结束时销毁。 是的,我明白了,抱歉,我可能没有问对,我想知道更多,Neo4jClient 在保持一个连接打开或是否应该不断打开连接方面的最佳做法是什么打开和关闭每个请求的连接。我没有看到任何类型的连接池选项,例如 MongoDB C# 驱动程序句柄,所以我只是想了解是否需要在此基础上构建。

以上是关于ASP.NET 和 Neo4jClient - 在哪里存储连接?的主要内容,如果未能解决你的问题,请参考以下文章

使用 neo4jclient 确保唯一节点

Neo4jClient:对 CRUD API 的质疑

Neo4jClient "CASE WHEN" 连同返回

如何在c#neo4jClient中创建一个唯一节点(如果已经存在则不重复)?

C# Neo4jClient 任务取消异常

在 f# 中使用 Neo4jClient 创建带标签的节点