C#应用XML作为数据库的快速开发框架实现方法
本文实例讲述了C#应用XML作为数据库的快速开发框架实现方法。分享给大家供大家参考。具体如下:
背景
我经常应用C#开发一些小的桌面程序,这些桌面程序往往有以下几个特点:
①程序比较小,开发周期很短。
②程序的数据量不大,多数情况下不超过1万行记录。
③对程序的性能要求不高。
④程序并发很少或者基本没有。
⑤尽量程序部署简单。
因为C#程序很多情况下都是CURD,结合上面的需求,我一直考虑做一个简单的框架,以达到快速开发的目的。应用XML序列化(XmlSerializer)功能,我开发了一个简单符合上面要求的底层框架。
框架思路
我准备用XML文件作为数据存储,为了保证数据同步,同时在内存中存储一份数据,每次操作时,都是操作内存中的数据,操作完之后再同步到数据库中。
另外,为了保证框架的易用性,我把底层实现写成了一个泛型类,所有操作类继承此泛型类。
框架功能描述
框架主要包括以下几个功能:
①应用XML文件作为数据库,不依赖其他数据库系统。
②对外提供基本的CURD功能。
③减少配置,做到0配置。
数据会存储在运行目录下面的data目录下,数据文件可以由开发者指定,也可以采用默认数据文件。
框架应用示例
如何应用框架进行开发呢?我把框架打成了一个DLL文件,开发项目时,需要引用这个DLL。开发者每定义一个实体类,需要对应定义一个操作类,此操作类需要继承我的泛型操作类。
注意:实体类需要有一个string类型的ID,我一般用GUID
实体类示例代码:
{
publicclassCodeEntity
{
publicstringId{get;set;}
publicstringKey{get;set;}
publicstringLang{get;set;}
publicbyte[]RealContent{get;set;}
}
}
我把操作类写成了单例模式,操作类示例代码:
{
publicclassCodeBll:Wisdombud.xmldb.BaseXmlBll<CodeEntity>
{
privatestaticCodeBllinst=newCodeBll();
privateCodeBll(){}
publicstaticCodeBllgetInst()
{
returninst;
}
}
}
如何应用:
XML文件的内容
<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.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>();
}
}
}
}
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#程序设计有所帮助。
相关文章
- c# 连接ACCESS 数据库 OleDbCommand OleDbDataReader
- AngouriMath: 用于C#和F#的开源跨平台符号代数库
- c# listview排序功能_c#入门
- 利用 C# 中的 FileSystemWatcher 制作一个文件夹监控小工具
- C与Oracle数据库备份安全可靠解决方案(c# oracle 备份)
- asp.net(c#)判断远程图片是否存在
- c#asp.net动态创建sql数据库表的方法
- c#代码自动修改解决方案下任意文件实例
- C#读取数据库返回泛型集合详解(DataSetToList)
- c#瀛?绗︿覆?肩被??涓?寮??ㄧ被??姣?杈?绀轰?
- c#数据绑定之向查询中添加参数(.Net连接外部数据库)
- c#获得目标服务器中所有数据库名、表名、列名的实现代码
- C#串口通信实现方法
- C#使用晚绑定来实现压缩Access数据库的方法
- C#基于数据库存储过程的AJAX分页实例