C#应用XML作为数据库的快速开发框架实现方法
本文实例讲述了C#应用XML作为数据库的快速开发框架实现方法。分享给大家供大家参考。具体如下:
背景
我经常应用C#开发一些小的桌面程序,这些桌面程序往往有以下几个特点:
①程序比较小,开发周期很短。
②程序的数据量不大,多数情况下不超过1万行记录。
③对程序的性能要求不高。
④程序并发很少或者基本没有。
⑤尽量程序部署简单。
因为C#程序很多情况下都是CURD,结合上面的需求,我一直考虑做一个简单的框架,以达到快速开发的目的。应用XML序列化(XmlSerializer)功能,我开发了一个简单符合上面要求的底层框架。
框架思路
我准备用XML文件作为数据存储,为了保证数据同步,同时在内存中存储一份数据,每次操作时,都是操作内存中的数据,操作完之后再同步到数据库中。
另外,为了保证框架的易用性,我把底层实现写成了一个泛型类,所有操作类继承此泛型类。
框架功能描述
框架主要包括以下几个功能:
①应用XML文件作为数据库,不依赖其他数据库系统。
②对外提供基本的CURD功能。
③减少配置,做到0配置。
数据会存储在运行目录下面的data目录下,数据文件可以由开发者指定,也可以采用默认数据文件。
框架应用示例
如何应用框架进行开发呢?我把框架打成了一个DLL文件,开发项目时,需要引用这个DLL。开发者每定义一个实体类,需要对应定义一个操作类,此操作类需要继承我的泛型操作类。
注意:实体类需要有一个string类型的ID,我一般用GUID
实体类示例代码:
namespacezDash { publicclassCodeEntity { publicstringId{get;set;} publicstringKey{get;set;} publicstringLang{get;set;} publicbyte[]RealContent{get;set;} } }
我把操作类写成了单例模式,操作类示例代码:
namespacezDash { publicclassCodeBll:Wisdombud.xmldb.BaseXmlBll<CodeEntity> { privatestaticCodeBllinst=newCodeBll(); privateCodeBll(){} publicstaticCodeBllgetInst() { returninst; } } }
如何应用:
CodeBll.getInst().Insert(entity);
XML文件的内容
<?xmlversion="1.0"?> <ArrayOfCodeEntityxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <CodeEntity> <Id>1</Id> <Key>符号</Key> <Lang>C#</Lang> <RealContent>e1</RealContent> </CodeEntity> <CodeEntity> <Id>2</Id> <Key>符号1</Key> <Lang>C#</Lang> <RealContent>e1</RealContent> </CodeEntity> </ArrayOfCodeEntity>
由上面的例子可以看到,应用此框架进行开发还是非常容易的。
总结
框架优点:
①快速开发,完全不需要考虑底层
②易于部署
③框架代码比较短小,总共200行左右。
框架缺点:
①效率低下
②未考虑并发,非线程安全
后续还会介绍如何应用这个框架开发一个代码片段管理系统
附:框架源代码
usingSystem; usingSystem.Collections.Generic; usingSystem.IO; usingSystem.Reflection; usingSystem.Xml.Serialization; namespaceWisdombud.xmldb { publicclassXmlSerializerBll<T> { privatestaticXmlSerializerBll<T>instance; privatestringdbFile; publicstringDbfile { get{returndbFile;} set { if(!string.IsNullOrEmpty(value)&&!value.Equals(dbFile)) { this.entityList.Clear(); } dbFile=value; this.ReadDb(); } } privateList<T>entityList=newList<T>(); privateXmlSerializerBll() { this.SetDbFile(); this.ReadDb(); } privatevoidSetDbFile() { stringfolder=Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"data"); try { if(Directory.Exists(folder)==false) { Directory.CreateDirectory(folder); } Typetype=typeof(T); if(string.IsNullOrEmpty(this.Dbfile)) {this.Dbfile=Path.Combine(folder,type.Name+".xml");} } catch(Exceptionex) { Console.WriteLine(ex.Message); } } publicstaticXmlSerializerBll<T>GetInstance() { if(instance==null) { instance=newXmlSerializerBll<T>(); } returninstance; } publicvoidInsert(Tentity) { this.entityList.Add(entity); this.WriteDb(); } publicvoidInsertRange(IList<T>list) { this.entityList.AddRange(list); this.WriteDb(); } publicSystem.Collections.Generic.List<T>SelectBy(stringname,Objectvalue) { System.Collections.Generic.List<T>list=newList<T>(); if(value==null) { returnlist; } Typet=typeof(T); foreach(varinstinthis.entityList) { foreach(PropertyInfoproint.GetProperties()) { if(pro.Name.ToLower()==name.ToLower()) { if(value.ToString()==(pro.GetValue(inst,null)??string.Empty).ToString()) { list.Add(inst); } } } } returnlist; } publicTSelectById(stringid) { Typet=typeof(T); foreach(varinstinthis.entityList) { foreach(PropertyInfoproint.GetProperties()) { if(pro.Name.ToLower()=="id") { if(id==(pro.GetValue(inst,null)??string.Empty).ToString()) { returninst; } } } } returndefault(T); } publicvoidUpdateById(Tentity) { Typet=typeof(T); stringid=string.Empty; foreach(PropertyInfoproint.GetProperties()) { if(pro.Name.ToLower()=="id") { id=(pro.GetValue(entity,null)??string.Empty).ToString(); break; } } this.DeleteById(id); this.Insert(entity); } publicvoidDeleteById(stringid) { Typet=typeof(T); Tentity=default(T); foreach(varinstinthis.entityList) { foreach(PropertyInfoproint.GetProperties()) { if(pro.Name.ToLower()=="id") { if((pro.GetValue(inst,null)??string.Empty).ToString()==id) { entity=inst; gotoFinishLoop; } } } } FinishLoop: this.entityList.Remove(entity); this.WriteDb(); } publicList<T>SelectAll() { this.ReadDb(); returnthis.entityList; } publicvoidDeleteAll() { this.entityList.Clear(); this.WriteDb(); } privatevoidWriteDb() { XmlSerializerks=newXmlSerializer(typeof(List<T>)); FileInfofi=newFileInfo(this.Dbfile); vardir=fi.Directory; if(!dir.Exists) { dir.Create(); } Streamwriter=newFileStream(this.Dbfile,FileMode.Create,FileAccess.ReadWrite); ks.Serialize(writer,this.entityList); writer.Close(); } privatevoidReadDb() { if(File.Exists(this.Dbfile)) { XmlSerializerks=newXmlSerializer(typeof(List<T>)); Streamreader=newFileStream(this.Dbfile,FileMode.Open,FileAccess.ReadWrite); this.entityList=ks.Deserialize(reader)asList<T>; reader.Close(); } else { this.entityList=newList<T>(); } } } }
usingSystem.Collections.Generic; namespaceWisdombud.xmldb { publicclassBaseXmlBll<T>whereT:new() { publicstringDbFile { get{returnthis.bll.Dbfile;} set{bll.Dbfile=value;} } privateXmlSerializerBll<T>bll=XmlSerializerBll<T>.GetInstance(); publicvoidDelete(stringid) { varentity=this.Select(id); bll.DeleteById(id); } publicvoidInsert(Tentity) { bll.Insert(entity); } publicvoidInsert(List<T>list) { bll.InsertRange(list); } publicSystem.Collections.Generic.List<T>SelectAll() { returnbll.SelectAll(); } publicvoidUpdate(stringoldId,Tentity) { bll.UpdateById(entity); } publicTSelect(stringid) { returnbll.SelectById(id); } publicSystem.Collections.Generic.List<T>SelectBy(stringname,objectvalue) { returnbll.SelectBy(name,value); } publicvoidDeleteAll() { bll.DeleteAll(); } } }
希望本文所述对大家的C#程序设计有所帮助。