• 以对象的方式来访问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数据表。

  • 相关阅读:
    react-webpack
    react
    重置手机过程
    运用 Node-RED 开发 LoRa 应用
    IBM Node-RED 安装与使用教程
    Node-RED 入门教程:简介
    Thingsboard 3.0 修改 Title、默认语言、主题颜色
    Thingsboard 3.0 通过 tb-gateway 网关接入 MQTT 设备教程
    Thingsboard 入门学习笔记:属性
    ThingsBoard 3.0 版本发布
  • 原文地址:https://www.cnblogs.com/forcheng/p/5329635.html
Copyright © 2020-2023  润新知