NCF想必看過我之前發的NCF的文章的同學們都已經很熟悉了
今天我們要來聊一聊的是NCF遇到Azure Cosmos DB後會碰撞出什麼樣的火花,讓我們一起往下看
我們先來說說什麼是Azure Cosmos DB
Azure Cosmos DB 是一個完全託管的無伺服器 NoSQL 資料庫,適用於任何大小或規模的高效能應用程式。獲得保證的單位數毫秒效能和 99.999% 的可用性,由 SLA 提供支援,自動和即時可伸縮性,適用於 NoSQL 資料庫(包括 MongoDB 和 Cassandra)的企業級安全性和開源 API。使用多區域寫入和資料複製,在全球任何位置享受快速寫入和讀取功能。使用適用於 Azure Cosmos DB 的 Azure Synapse Link,通過無 ETL (提取、轉換、載入)分析獲取實時資料的見解。
下載地址:https://github.com/NeuCharFramework/NCF (歡迎大家Star)
分支:master
開啟資料庫組態檔
修改Sql-Server節點的內容,如下所示
修改這三個位置即可
點選黃色背景區域的後邊的按鈕安裝
點選開啟模組生成器
選擇生成XNCF,輸入對應的引數,即可生成模組,這裡以Azure Cosmos DB模組為例
進入主頁的頁面如上圖所示。
需要載入0.2.26的版本,裡面對Azure Cosmos DB的Core Api進行了優化,方便大家快速的完成應用
建立一個管理的介面
在Register.Area中增加一個選單的選項來進入CosmosDB的管理介面
@page @model ML.Xncf.CosmosDB.Areas.Admin.Pages.CosmosDB.ManageModel @{ ViewData["Title"] = "Azure Cosmos DB Manage"; Layout = "_Layout_Vue"; } @*參考網址:https://element.eleme.cn/#/zh-CN/component/table*@ @section HeaderContent{ <style> .mb-10 { margin-bottom: 10px; } </style> } @section breadcrumbs { <el-breadcrumb-item>擴充套件模組</el-breadcrumb-item> <el-breadcrumb-item>Azure Cosmos DB</el-breadcrumb-item> <el-breadcrumb-item>管理</el-breadcrumb-item> } <div> <el-container class="mb-10"> <el-row> <el-button @@click="addItem()" type="primary">新增</el-button> <el-button @@click="toggleSelection([cosmosData[0], cosmosData[1]])">選中前2行</el-button> <el-button @@click="toggleSelection()">取消選擇</el-button> </el-row> </el-container> <el-container> <el-table tooltip-effect="dark" ref="multipleTable" :data="cosmosData.filter(data => !search || data.lastName.toLowerCase().includes(search.toLowerCase()))" style="width: 100%" @@selection-change="handleSelectionChange"> <el-table-column type="selection" show-overflow-tooltip="true" width="55"> </el-table-column> <el-table-column label="Id" prop="id"> </el-table-column> <el-table-column label="Key" prop="partitionKey"> </el-table-column> <el-table-column label="LastName" prop="lastName"> </el-table-column> <el-table-column align="right"> <template slot="header" slot-scope="scope"> <el-input v-model="search" size="mini" placeholder="輸入關鍵字搜尋" /> </template> <template slot-scope="scope"> <el-button size="mini" @@click="handleEdit(scope.$index, scope.row)">Edit</el-button> <el-button size="mini" type="danger" @@click="handleDelete(scope.$index, scope.row)">Delete</el-button> </template> </el-table-column> </el-table> </el-container> </div>
以上程式碼內容完全可以參考Element UI中的元件部分,找到自己想使用的,直接使用就好了
@section scripts{ <script> var app = new Vue({ el: "#app", data() { return { moduleData: null, uid: '', search: '', tableData: [], cosmosData:[], multipleSelection: [] } }, computed: { backgroundColor() { let rgba = `rgba(${this.moduleData.colorDto.red},${this.moduleData.colorDto.green},${this.moduleData.colorDto.blue},1)` return rgba; } }, mounted() { this.getList(); }, methods: { async getList(){ const res = await service.get('/Admin/CosmosDB/Manage?handler=List'); this.cosmosData = res.data.data; }, async addItem(){ const res = await service.get('/Admin/CosmosDB/Manage?handler=Add'); this.getList(); }, async handleEdit(index, row) { console.log(index, row); const res = await service.get('/Admin/CosmosDB/Manage?handler=Edit&id=' + row.id + '&key=' + row.partitionKey); this.getList(); }, async handleDelete(index, row) { console.log(index, row); const res = await service.get('/Admin/CosmosDB/Manage?handler=Delete&id=' + row.id + '&key=' + row.partitionKey); this.getList(); }, toggleSelection(rows) { if (rows) { rows.forEach(row => { this.$refs.multipleTable.toggleRowSelection(row); }); } else { this.$refs.multipleTable.clearSelection(); } }, handleSelectionChange(val) { this.multipleSelection = val; } } }); </script> }
這是上一步中UI介面上對應的按鈕,Table元件需要呼叫的資料請求及按鈕觸發的方法
在Domain/Services下建立業務類CosmosDBService
public class CosmosDBService { private string strEndpointUrl = "https://localhost:8081"; private string strPrimaryKey = "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="; private string strApplicationName = "CosmosDBDotnetQuickstart"; private string DatabaseName = "db01"; private string ContainerName = "c01"; public CosmosDBService() { } public async Task<List<Family>> GetList() { CoreApi coreApi = new CoreApi(strEndpointUrl, strPrimaryKey, strApplicationName); await coreApi.CreateDatabaseIfNotExistsAsync("TODOList01"); await coreApi.CreateContainerAsync(ContainerName); await coreApi.ScaleContainerAsync(); await coreApi.AddItemsToContainerAsync(); var sqlQueryText = "SELECT * FROM c WHERE 1=1 "; var result = await coreApi.QueryItemsAsync<Family>(sqlQueryText); return result; } public async Task AddItem() { CoreApi coreApi = new CoreApi(strEndpointUrl, strPrimaryKey, strApplicationName); await coreApi.CreateDatabaseIfNotExistsAsync("TODOList01"); await coreApi.CreateContainerAsync(ContainerName); await coreApi.ScaleContainerAsync(); string strName = "MartyZane"; Family andersenFamily = new Family { Id = $"{strName}{DateTime.Now.ToString("yyyyMMddHHmmssfff")}", PartitionKey = $"{strName}{DateTime.Now.ToString("yyyyMMddHHmmssfff")}", LastName = $"{strName}{DateTime.Now.ToString("yyyyMMddHHmmssfff")}", Parents = new Parent[] { new Parent { FirstName = "Thomas" }, new Parent { FirstName = "Mary Kay" } }, Children = new Child[] { new Child { FirstName = "Henriette Thaulow", Gender = "female", Grade = 5, Pets = new Pet[] { new Pet { GivenName = "Fluffy" } } } }, Address = new Address { State = "WA", County = "King", City = "Seattle" }, IsRegistered = false }; await coreApi.AddItemsToContainerAsync<Family>(andersenFamily, andersenFamily.Id, andersenFamily.PartitionKey); } public async Task UpdateItem(string id, string key) { CoreApi coreApi = new CoreApi(strEndpointUrl, strPrimaryKey, strApplicationName); await coreApi.CreateDatabaseIfNotExistsAsync("TODOList01"); await coreApi.CreateContainerAsync(ContainerName); await coreApi.ScaleContainerAsync(); await coreApi.ReplaceFamilyItemAsync(id,key); } public async Task DeleteItem(string id,string key) { CoreApi coreApi = new CoreApi(strEndpointUrl, strPrimaryKey, strApplicationName); await coreApi.CreateDatabaseIfNotExistsAsync("TODOList01"); await coreApi.CreateContainerAsync(ContainerName); await coreApi.ScaleContainerAsync(); await coreApi.DeleteFamilyItemAsync(id,key); } }
以上原始碼,是所有的Service中的業務方法
在此檔案中加入替換下面的原始碼
public class ManageModel : Senparc.Ncf.AreaBase.Admin.AdminXncfModulePageModelBase { private readonly IServiceProvider serviceProvider; public ManageModel(IServiceProvider serviceProvider, Lazy<XncfModuleService> xncfModuleService) : base(xncfModuleService) { this.serviceProvider = serviceProvider; } public async Task<IActionResult> OnGetListAsync() { CosmosDBService cosmosDBService = new CosmosDBService(); var result = await cosmosDBService.GetList(); return Ok(result); } public async Task<IActionResult> OnGetAddAsync() { CosmosDBService cosmosDBService = new CosmosDBService(); cosmosDBService.AddItem(); return Ok("200"); } public async Task<IActionResult> OnGetEditAsync(string id, string key) { CosmosDBService cosmosDBService = new CosmosDBService(); cosmosDBService.UpdateItem(id,key); return Ok("200"); } public async Task<IActionResult> OnGetDeleteAsync(string id,string key) { CosmosDBService cosmosDBService = new CosmosDBService(); cosmosDBService.DeleteItem(id,key); return Ok("200"); } }
以上內容就是我們今天要聊的範例的所有原始碼
經過上面的操作後,呈現出來的樣子如圖所示,列表的展示,查詢,新增,修改,刪除功能就全部擁有了。
那麼這些資料有沒有工具可以視覺化的檢視呢?
答案:是肯定的,就是我們馬上要聊的Azure Cosmos DB Emulator
圖中展示的是Azure Cosmos DB的首頁
這個是資料的資源管理器,可以點選檢視的資料的內容
還可以根據自己的查詢條件來快速查詢資料
查詢的語句沿用了SQL Server的一些語法,大家可以去嘗試一下
平均的請求效率在幾十毫秒,所以這個Azure Cosmos DB可以作為我們另外的一個管理資料的選擇之一
到此一個NCF整合Azure Cosmos DB的Demo範例就完整展示了,希望能夠幫助到您。
後期精彩內容(敬請關注)