[12屆 鐵人賽] [Day19] Neo4j with C# 程式串接實作 part1 - 基本連接 === ###### tags: `iT鐵人賽` `Neo4j` ## 前情提要 原本計畫是第 20 篇的時候才要進入這個主題的 不過前面那個章節寫到有點矇,可以能需要更多的準備時間才能把那些主題寫到更好 所以決定先擱置,先來寫些有把握的東西,也就是 Neo4j 該如何 C# 串接 為什麼選 C# 唯一原因:啊我工作就用 C# 啊 ## Install Package 首先拿出你的 Visual Studio 新建一個專案 在你要連接 Neo4j 前你要先裝官方提供的 `Neo4j.Driver` Package [nuget 連結](https://www.nuget.org/packages/Neo4j.Driver) ![](https://i.imgur.com/hZGkDkK.png) 裝好之後我們就可以開始建立基本的連接了 ## 基本連線程式 先上個[官網](https://neo4j.com/developer/dotnet/) For .NET 的連結 在開始寫基礎之前我們要先準備一個 Neo4j Server,參考第三~第五篇 再來你可以直接把官網提供的程式碼直接貼上去 ↓↓↓↓ ```csharp public class HelloWorldExample : IDisposable { private readonly IDriver _driver; public HelloWorldExample(string uri, string user, string password) { _driver = GraphDatabase.Driver(uri, AuthTokens.Basic(user, password)); } public void PrintGreeting(string message) { using (var session = _driver.Session()) //這裡會錯 { var greeting = session.WriteTransaction(tx => //這裡會錯 { var result = tx.Run("CREATE (a:Greeting) " + //這裡會錯 "SET a.message = $message " + "RETURN a.message + ', from node ' + id(a)", new {message}); return result.Single()[0].As<string>(); //這裡也會錯 }); Console.WriteLine(greeting); } } public void Dispose() { _driver?.Dispose(); } public static void Main() { using (var greeter = new HelloWorldExample("bolt://localhost:7687", "neo4j", "password")) { greeter.PrintGreeting("hello, world"); } } } ``` 然後你就會發現它噴錯 (゚∀゚) `Neo4j.Driver` 不知道在什麼時候,就已經移除了同步的寫法 可是官網居然完全沒跟上,到底 (゚∀゚;) 所以我們來稍微幫他修改一下吧 ### 解析官方原始程式 我先把官方的原始程式拆成兩大塊 會噴錯的部分 & 不會噴錯的部分 我們先來看看不會錯的地方吧 ```csharp public class HelloWorldExample : IDisposable { private readonly IDriver _driver; public HelloWorldExample(string uri, string user, string password) { _driver = GraphDatabase.Driver(uri, AuthTokens.Basic(user, password)); } public void Dispose() { _driver?.Dispose(); } public static void Main() { using (var greeter = new HelloWorldExample("bolt://localhost:7687", "neo4j", "password")) { greeter.PrintGreeting("hello, world"); } } } ``` 結構好像怪怪的,先改一下 嗯,這樣合理多了,順手換一下 `class` 名稱 ```csharp public class Neo4jHandler : IDisposable { //Neo4j連線基礎 private readonly IDriver _driver; public Neo4jHandler(string uri, string user, string password) { //建立基礎連線 _driver = GraphDatabase.Driver(uri, AuthTokens.Basic(user, password)); } //繼承自 IDisposable public void Dispose() { _driver?.Dispose(); } } class Program { static void Main(string[] args) { //基本宣告,這個應該不用解釋 using (var greeter = new Neo4jHandler("bolt://localhost:7687", "neo4j", "password")) { greeter.HelloWord("hello, world"); } } } ``` 這個架構可以用,之後就這樣用了,接著來看看會噴錯的那段吧 ```csharp public void PrintGreeting(string message) { using (var session = _driver.Session()) { var greeting = session.WriteTransaction(tx => { var result = tx.Run("CREATE (a:Greeting) " + "SET a.message = $message " + "RETURN a.message + ', from node ' + id(a)", new { message }); return result.Single()[0].As<string>(); }); Console.WriteLine(greeting); } } ``` 嗯~ 看起來有一段很明顯是 Cypher 的東西 所以翻譯一下這段,就是建立一個 `Node` 在讀回 `Node` 中的資料 OK,所以現在的問題是要如何執行一段 Cypher 以及回傳資料 讓我來改一下 ```csharp //改法 1 public async Task<string> HelloWord(string message) { string sql = $"CREATE (n:Greeting{{message:'{message}'}}) RETURN n.message + ' from node : '+ id(n)"; //建立交談 var session = _driver.AsyncSession(); //開始交談 var transaction = await session.BeginTransactionAsync(); //執行 cypher 語法 var echo = await transaction.RunAsync(sql); //取得回傳 var result = await echo.ToListAsync(r => r[0].As<string>()); //提交變更 await transaction.CommitAsync(); return result[0]; } ``` 嗯,變了許多魔術呢 原本的那個結構改下去也不是不行 ```csharp //改法 2 public async Task<string> HelloWord(string message) { string sql = $"CREATE (n:Greeting{{message:'{message}'}}) RETURN n.message + ' from node : '+ id(n)"; var session = _driver.AsyncSession(); var greeting = await session.WriteTransactionAsync(async tx => { var result = await tx.RunAsync(sql); return await result.ToListAsync(r => r[0].As<string>()); }); return greeting[0]; } ``` 改法 1 跟改法 2 取得的結果會是一樣的,就看大家喜歡哪種寫法了 讓我們來看看執行的結果吧 ![](https://i.imgur.com/mnGELv3.png) 看起來是好了,來進資料庫看看吧 ![](https://i.imgur.com/nxAg5k9.png) 這樣基本的串接測試就完成了 --- 寫到 High 起來,才點無法收尾 ![](https://i.imgur.com/Skv20bK.gif) 今天簡單講了基本連接 之後的幾天會再來詳細講一些資料處理、格式轉換、或是一些應用之類的 這系列會寫幾篇我也不知道,預計是 4 篇 不過最近寫到後期計畫不斷的在調整 我也說不準w 下篇 **Neo4j with C# 程式串接實作 part2 - 更多的資料讀寫實作** 究竟鐵人賽能不能完賽呢,讓我們繼續看下去 --- ## 參考資料 [Neo4j - Using Neo4j from .NET](https://neo4j.com/developer/dotnet/) ## 紀錄 撰寫日期:2020/10/03 耗時: 應該在 2 小內