以對象的方式來訪問xml數據表(二)

来源:http://www.cnblogs.com/forcheng/archive/2016/04/04/5329635.html
-Advertisement-
Play Games

為什麼要以對象的方式來訪問xml數據表? 還記得,自己是在一次完成師兄佈置的任務時接觸到了xml,那時候需要用xml來作為數據文件,保存一個簡單的圖書管理系統的數據。於是就知道了,可以用xml文件來保存數據(而且比用簡單的文本文件保存數據規範的多,在訪問與讀取數據上面都十分方便),就這樣使用xml的 ...


  為什麼要以對象的方式來訪問xml數據表?

  還記得,自己是在一次完成師兄佈置的任務時接觸到了xml,那時候需要用xml來作為數據文件,保存一個簡單的圖書管理系統的數據。於是就知道了,可以用xml文件來保存數據(而且比用簡單的文本文件保存數據規範的多,在訪問與讀取數據上面都十分方便),就這樣使用xml的徵程開始了。

  自己做的第一個WPF桌面應用程式——備忘錄,就是用xml文件作為資料庫。而且那個時候考慮到以後可能會經常使用到xml文件作為資料庫,於是乎就寫了一個專門用於訪問xml文件的動態鏈接庫,這樣不僅可以提高代碼的重用性(用功一次,獲益無窮),而且還提高了軟體後期的維護效率(由於規範),動態鏈接庫實現的基本功能:將連接數據文件的過程和檢查規範全封裝在一個方法裡面(而數據表的屬性是通過數組傳參傳遞),將對數據的增、刪、查、改也全部封裝成各種方法,還封裝了一些屬性等等。但此時的自己還沒有面向對象開發的思維,最終在開發時還是以傳統的方式去訪問的xml數據表(Element(value))。

  這是我第一個版本的訪問xml的動態鏈接庫源碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.IO;
using System.Text.RegularExpressions;

namespace XmlIDataBase
{
    public class XmlDataBase
    {
        #region 私有欄位
        private string xmlFilePath;
        private string[] xmlProperties;
        private string noteName;
        #endregion

        #region 公有欄位
        public XElement Notes;
        #endregion

        #region 公有方法
        //連接數據文件
        public bool Connect(string path_, string noteName_, params string[] properties)
        {
            try
            {
                //匹配xml文件路徑
                if (!Regex.IsMatch(path_, @"^(?<fpath>([a-zA-Z]:\\)([\s\.\-\w]+\\)*)(?<fname>[\w]+.[\w]+)") || noteName_ == "" || path_.Length < 5 || path_.Substring(path_.Length - 3).ToLower() != "xml")
                {
                    return false;
                }
                noteName = noteName_;//記錄每條記錄的名稱
                xmlFilePath = path_;//記錄文件路徑

                if (path_.LastIndexOf("\\") > 0)
                {
                    path_ = path_.Substring(0, path_.LastIndexOf("\\"));
                }
                else
                {
                    path_ = "";
                }

                if (path_ != "" && !Directory.Exists(path_))
                {
                    Directory.CreateDirectory(path_);
                    var xmlFile = new StreamWriter(xmlFilePath);
                    xmlFile.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
                    xmlFile.WriteLine("<" + noteName + "s>");
                    xmlFile.WriteLine("</" + noteName + "s>");
                    xmlFile.Close();
                }
                else
                {
                    if (!File.Exists(xmlFilePath))
                    {
                        var xmlFile = new StreamWriter(xmlFilePath);
                        xmlFile.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
                        xmlFile.WriteLine("<" + noteName + "s>");
                        xmlFile.WriteLine("</" + noteName + "s>");
                        xmlFile.Close();
                    }
                }

                Notes = XElement.Load(xmlFilePath);
                xmlProperties = new string[properties.Length];
                xmlProperties = properties;//記錄每條記錄的屬性
                return true;
            }
            catch (Exception e)
            {
                throw e;
                //return false;
            }
        }

        //保存數據文件
        public bool SaveChanged()
        {
            try
            {
                Notes.Save(xmlFilePath);
                return true;
            }
            catch (Exception e)
            {
                throw e;
                //return false;
            }
        }

        //添加紀錄:添加到末尾(方法一)
        public bool AddNote(params string[] propertyValues)
        {
            try
            {
                if (propertyValues.Length == xmlProperties.Length)
                {
                    if (Notes.Elements(noteName).Count() > 0)
                    {
                        int newNo;
                        var lastNote = from Note in Notes.Elements() select Convert.ToInt32(Note.Attribute("No").Value);
                        newNo = lastNote.Max() + 1;
                        Notes.LastNode.AddAfterSelf(noteName, new XAttribute("No", newNo));
                        for (int i = 0; i < xmlProperties.Length; i++)
                        {
                            if (i == 0)
                            {
                                Notes.Elements().Last().AddFirst(new XElement(xmlProperties[i], propertyValues[i]));
                            }
                            else
                            {
                                Notes.Elements().Last().LastNode.AddAfterSelf(new XElement(xmlProperties[i], propertyValues[i]));
                            }
                        }
                    }
                    else
                    {
                        Notes.AddFirst(new XElement(noteName, new XAttribute("No", 1)));
                        for (int i = 0; i < xmlProperties.Length; i++)
                        {
                            if (i == 0)
                            {
                                Notes.Element(noteName).AddFirst(new XElement(xmlProperties[i], propertyValues[i]));
                            }
                            else
                            {
                                Notes.Element(noteName).LastNode.AddAfterSelf(new XElement(xmlProperties[i], propertyValues[i]));
                            }
                        }
                    }
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception e)
            {
                throw e;
                //return false;
            }

        }

        //添加記錄:添加到末尾(方法二)
        public bool AddNote(XElement newNote)
        {
            try
            {
                if (newNote.Elements().Count() == xmlProperties.Length)
                {
                    if (Notes.Elements(noteName).Count() > 0)
                    {
                        int newNo;
                        var lastNote = from Note in Notes.Elements() select Convert.ToInt32(Note.Attribute("No").Value);
                        newNo = lastNote.Max() + 1;
                        if(newNote.Attribute("No") == null)
                        {
                            newNote.Add(new XAttribute("No", newNo));
                        }
                        else
                        {
                            newNote.Attribute("No").Value = newNo.ToString();
                        }
                        Notes.Elements().Last().AddAfterSelf(newNote);
                    }
                    else
                    {
                        if (newNote.Attribute("No") == null)
                        {
                            newNote.Add(new XAttribute("No", 1));
                        }
                        else
                        {
                            newNote.Attribute("No").Value = "1";
                        }
                        Notes.AddFirst(newNote);
                    }
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception e)
            {
                throw e;
                //return false;
            }
        }

        //添加記錄:添加到開頭
        public bool AddFistNote(XElement newNote)
        {
            try
            {
                if (newNote.Elements().Count() == xmlProperties.Length)
                {
                    if (Notes.Elements(noteName).Count() > 0)
                    {
                        int newNo;
                        var lastNote = from Note in Notes.Elements() select Convert.ToInt32(Note.Attribute("No").Value);
                        newNo = lastNote.Max() + 1;
                        if (newNote.Attribute("No") == null)
                        {
                            newNote.Add(new XAttribute("No", newNo));
                        }
                        else
                        {
                            newNote.Attribute("No").Value = newNo.ToString();
                        }
                        Notes.AddFirst(newNote);
                    }
                    else
                    {
                        if (newNote.Attribute("No") == null)
                        {
                            newNote.Add(new XAttribute("No", 1));
                        }
                        else
                        {
                            newNote.Attribute("No").Value = "1";
                        }
                        Notes.AddFirst(newNote);
                    }
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception e)
            {
                throw e;
                //return false;
            }
        }

        //刪除記錄(單一索引)
        public bool DeletNote(string no = "", params string[] propertyValues)
        {
            try
            {
                bool okFlag = false;
                if (propertyValues.Length > xmlProperties.Length)
                {
                    return false;
                }
                else
                {
                    if (no == "") //按屬性值相等刪除
                    {
                        for (int i = 0; i < propertyValues.Length; i++)
                        {
                            if (propertyValues[i] == "") continue;
                            if (Notes.Elements(noteName).Count() == 0) return false;//數據文件內容為空
                            var proNotes = Notes.Elements(noteName).Elements(xmlProperties[i]).Where(m => m.Value == propertyValues[i]);
                            foreach (var item in proNotes)
                            {
                                item.Parent.Remove();
                                okFlag = true;
                            }
                        }
                    }
                    else //按編號相等刪除
                    {
                        if (Notes.Elements(noteName).Count() == 0) return false;//數據文件內容為空
                        var proNote = Notes.Elements(noteName).SingleOrDefault(m => m.Attribute("No").Value == no);
                        if (proNote != null)
                        {
                            proNote.Remove();
                            okFlag = true;
                        }
                    }
                    return okFlag;
                }
            }
            catch (Exception e)
            {
                throw e;
                //return false;
            }
        }

        //修改記錄(編號索引:方法一)
        public bool ModifyNote(string no, params string[] propertyValues)
        {
            try
            {
                if (no == "" || propertyValues.Length != xmlProperties.Length)
                {
                    return false;
                }
                bool okFlag = false;
                if (Notes.Elements(noteName).Count() == 0) return false;//數據文件內容為空
                var proNote = Notes.Elements(noteName).Attributes("No").SingleOrDefault(m => m.Value == no);
                if (proNote != null)
                {
                    var proSubNotes = proNote.Parent.Elements();
                    int i = 0;
                    foreach (var item in proSubNotes)
                    {
                        item.Value = propertyValues[i++];
                    }
                    okFlag = true;
                }
                return okFlag;
            }
            catch (Exception e)
            {
                throw e;
                //return false;
            }
        }

        //修改記錄(編號索引:方法二用一個新的節點(No值不變)替代)
        public bool ModifyNote(string no, XElement noteModified)
        {
            try
            {
                if (no == "" || noteModified.Elements().Count() != xmlProperties.Length)
                {
                    return false;
                }
                bool okFlag = false;
                if (Notes.Elements(noteName).Count() == 0) return false;//數據文件內容為空
                var proNote = Notes.Elements(noteName).Attributes("No").SingleOrDefault(m => m.Value == no);
                if (proNote != null)
                {
                    proNote.Parent.ReplaceWith(noteModified);
                }
                return okFlag;

            }
            catch (Exception e)
            {
                throw e;
                //return false;
            }
        }

        //查詢記錄(單一索引)
        public IEnumerable<XElement> QueryNote(string no = "", params string[] propertyValues)
        {
            IEnumerable<XElement> result = null;
            try
            {
                if (no == "" && propertyValues.Length == 0)//返回所有數據
                {
                    return Notes.Elements(noteName);
                }
                if (no == "" && propertyValues.Length != 0)
                {
                    for (int i = 0; i < propertyValues.Length; i++)
                    {
                        if (propertyValues[i] == "") continue;
                        if (Notes.Elements(noteName).Count() == 0) return result;//數據文件內容為空
                        var proNotes = Notes.Elements(noteName).Elements(xmlProperties[i]).Where(m => m.Value == propertyValues[i]);
                        return proNotes;
                    }
                }
                else
                {
                    if (Notes.Elements(noteName).Count() == 0) return result;//數據文件內容為空
                    var proNote = Notes.Elements(noteName).Attributes("No").SingleOrDefault(m => m.Value == no);
                    if (proNote != null)
                    {
                        result = new XElement[] { proNote.Parent };
                    }
                }

                return result;

            }
            catch (Exception e)
            {
                throw e;
                //return false;
            }

        }

        //獲取記錄的條數
        public int Count()
        {
            try
            {
                return Notes.Elements(noteName).Count();
            }
            catch (Exception e)
            {
                throw e;
                //return false;
            }
        }

        //獲取所有記錄
        public IEnumerable<XElement> AllNotes()
        {
            try
            {
                return Notes.Elements(noteName);
            }
            catch (Exception e)
            {
                throw e;
                //return false;
            }
        }

        //獲取最後一條記錄的No
        public int GetLastNoteNo()
        {
            try
            {
                if (Notes.Elements(noteName).Count() > 0)
                    return (from Note in Notes.Elements(noteName) select Convert.ToInt32(Note.Attribute("No").Value)).Max();
                else
                    return 0;
            }
            catch (Exception e)
            {
                throw e;
                //return false;
            }
        }
        #endregion
    }
}
View Code

  後面自己又用xml文件作為資料庫開發了一個WPF桌面應用程式和一個小型的網站,此時的動態鏈接庫還沒有什麼大的改進,只是對其中的代碼進行了一些優化。直到那一天,我在用ASP.NET MVC開發工作室的門戶網站(此時不再是用xml文件作為資料庫,而是用的SQL Sever),涉及到對網站後臺資料庫的訪問時,我發現了Entity Framework訪問資料庫的方便簡潔之處,首先直接在Model裡面寫一個能夠映射一張數據表的類(一般只需包含對應的屬性即可),然後使用資料庫上下文介面DbContext來輕輕鬆松訪問資料庫。先看看代碼:

  Model裡面的User類:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace Test.Models
{
    public class User
    {
        [Required]
        public Int32 Id { get; set; }

        [Required]
        [DisplayName("名字")]
        public String Name { get; set; }

        [Required]
        [DisplayName("用戶名")]
        public String Account { get; set; }

        [Required]
        [DisplayName("密碼")]
        public String Password { get; set; }

        //創建時間
        [Required]
        public DateTime CreateTime { get; set; }

        //標識是否為管理員
        [Required]
        public Boolean IsAdmin { get; set; }

    }
}
View Code

  繼承了DbContext介面的類:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;

namespace Test.Models
{
    public class WS_WebAppContext : DbContext
    {

        public virtual DbSet<User> Users { get; set; }

        public WS_WebAppContext() : base("name=WS_WebAppContext")
        {
            
        }
    }
}
View Code

  Control裡面輕鬆訪問,只是給出了登錄驗證部分:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using Test.Models;

namespace Test.Controllers
{
    public class HomeController : Controller
    {
        
        WS_WebAppContext entity = new WS_WebAppContext();
        
         //登錄頁面
        public ActionResult Login()
        {
            return View();
        }
        
        //檢查登錄信息
        [HttpPost]
        public ActionResult Login(User u)
        {
            var logined = entity.Users.SingleOrDefault(m => m.Account == u.Account);
            if (!string.IsNullOrWhiteSpace(u.Password) && logined != null && logined.Password == u.Password)
            {
                String role = "User";
                if (logined.IsAdmin)
                {
                    role = "Admin";
                }
                FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
                    1,
                    logined.Id.ToString(),
                    DateTime.Now,
                    DateTime.Now.AddMinutes(120),
                    false,
                    role
                   );
                string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
                HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
                Response.Cookies.Add(authCookie);
                if (logined.IsAdmin)
                {
                    return RedirectToAction("Index", "Admin");//跳轉到管理員的主頁
                }
                else
                {
                    return RedirectToAction("Index", "User");//跳轉到用戶的主頁
                }
            }
            else
            {
                return Content("<script>alert('用戶名或密碼錯誤!');local.href='/Home/Index'</script>");
            }
        }
    }
}
View Code

  HomeController裡面的entity對象就是專門用來訪問資料庫的,通過它可以簡單方便的對資料庫裡面的數據表(entity.Users就對應著資料庫中的用戶表)進行增刪查改。

當我看到它的簡潔方便之處時,靈感來了,我就在想,為什麼我不用這種以對象的方式來實現那個專門用於訪問xml數據文件的動態鏈接庫呢?

  對於為什麼要以對象的方式來訪問xml數據表就簡單介紹到這裡,關鍵是你要動手去開發過,你才知道這種方式的簡潔方便之處。

  讓我們在(三)中接著詳談怎樣以對象的方式來訪問xml數據表。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、引言 在前一篇文章已經詳細介紹了SignalR了,並且簡單介紹它在Asp.net MVC 和WPF中的應用。在上篇博文介紹的都是群發消息的實現,然而,對於SignalR是為了實時聊天而生的,自然少了不像QQ一樣的端對端的聊天了。本篇博文將介紹如何使用SignalR來實現類似QQ聊天的功能。 二、 ...
  • 作者:[美]Adam Freeman 來源:《精通ASP.NET MVC 4》 本文將繼續構建 SportsStore 示例應用程式。在上一章中,添加了對購物車的基本支持,現在打算改善並完成其功能。 1.使用模型綁定 MVC 框架使用了一個叫作“模型綁定”的系統,以便通過 HTTP 請求來創建一些 ...
  • ASP.NET Core在啟動以及後續針對每個請求的處理過程中的各個環節都需要相應的組件提供相應的服務,為了方便對這些組件進行定製,ASP.NET通過定義介面的方式對它們進行了“標準化”,我們將這些標準化的組件稱為服務,ASP.NET在內部專門維護了一個DI容器來提供所需的服務。要瞭解這個DI容器以... ...
  • ??二元操作符在對first??second求值時,大致會經歷以下步驟: 1)對first進行求值; 2)如果結果非空,則該結果就是整個表達式的結果; 3)否則求second的值,其結果作為整個表達式的結果。 例如: ...
  • 當我們初學Winform的時候被其神奇的事件功能所吸引,當點擊一個按鈕時,便會跳到我們所寫的點擊方法當中去。然而這並不符合我們對方法的理解,究竟.net在後面幫助我們實現了什麼。我們怎樣模擬其事件的實現呢。下麵先從Button的Click方法說起。 1.首先查看設計器自動生成的代碼 EventHan ...
  • 目錄結構: 1. SVN伺服器搭建和使用-VisualSVNServer 2. SVN客戶端安裝和使用-TortoiseSVN 3. TortoiseSVN使用方法 SVN簡介 SVN是Subversion的簡稱,是一個開放源代碼的版本控制系統,相較於RCS、CVS,它採用了分支管理系統,它的設計目 ...
  • 1,.NET Framework:是開發平臺,包含兩大部分: ①龐大的代碼庫(類庫),可以在客戶語言(C#,VB)中來使用這些代碼 ②Common Language Runtime,負責管理應用程式的執行 2,使用.NET Framework編寫應用程式,就是使用.NET 代碼庫編寫程式。 3,C# ...
  • 0x00 前言 關於TDD測試驅動開發的文章已經有很多了,但是在游戲開發尤其是使用Unity3D開發游戲時,卻聽不到特別多關於TDD的聲音。那麼本文就來簡單聊一聊TDD如何在U3D項目中使用以及如何使用U3D 5.3.X之後版本已經集成的單元測試模塊Editor Test Runner。 0x01 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...