C#应用XML作为数据库的快速开发框架实现方法
本文实例讲述了c#应用xml作为数据库的快速开发框架实现方法。分享给大家供大家参考。具体如下:
背景
我经常应用c#开发一些小的桌面程序,这些桌面程序往往有以下几个特点:
① 程序比较小,开发周期很短。
② 程序的数据量不大,多数情况下不超过1万行记录。
③ 对程序的性能要求不高。
④ 程序并发很少或者基本没有。
⑤ 尽量程序部署简单。
因为c#程序很多情况下都是curd,结合上面的需求,我一直考虑做一个简单的框架,以达到快速开发的目的。应用xml序列化(xmlserializer)功能,我开发了一个简单符合上面要求的底层框架。
框架思路
我准备用xml文件作为数据存储,为了保证数据同步,同时在内存中存储一份数据,每次操作时,都是操作内存中的数据,操作完之后再同步到数据库中。
另外,为了保证框架的易用性,我把底层实现写成了一个泛型类,所有操作类继承此泛型类。
框架功能描述
框架主要包括以下几个功能:
① 应用xml文件作为数据库,不依赖其他数据库系统。
② 对外提供基本的curd功能。
③ 减少配置,做到0配置。
数据会存储在运行目录下面的data目录下,数据文件可以由开发者指定,也可以采用默认数据文件。
框架应用示例
如何应用框架进行开发呢?我把框架打成了一个dll文件,开发项目时,需要引用这个dll。开发者每定义一个实体类,需要对应定义一个操作类,此操作类需要继承我的泛型操作类。
注意:实体类需要有一个string类型的id,我一般用guid
实体类示例代码:
{
public class codeentity
{
public string id { get; set; }
public string key { get; set; }
public string lang { get; set; }
public byte[] realcontent { get; set; }
}
}
我把操作类写成了单例模式,操作类示例代码:
{
public class codebll : wisdombud.xmldb.basexmlbll<codeentity>
{
private static codebll inst = new codebll();
private codebll() { }
public static codebll getinst()
{
return inst;
}
}
}
如何应用:
xml文件的内容
<arrayofcodeentity xmlns: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行左右。
框架缺点:
① 效率低下
② 未考虑并发,非线程安全
后续还会介绍如何应用这个框架开发一个代码片段管理系统
附:框架源代码
using system.collections.generic;
using system.io;
using system.reflection;
using system.xml.serialization;
namespace wisdombud.xmldb
{
public class xmlserializerbll<t>
{
private static xmlserializerbll<t> instance;
private string dbfile;
public string dbfile
{
get { return dbfile; }
set
{
if (!string.isnullorempty(value) && !value.equals(dbfile))
{
this.entitylist.clear();
}
dbfile = value;
this.readdb();
}
}
private list<t> entitylist = new list<t>();
private xmlserializerbll()
{
this.setdbfile();
this.readdb();
}
private void setdbfile()
{
string folder = path.combine(appdomain.currentdomain.basedirectory, "data");
try
{
if (directory.exists(folder) == false)
{
directory.createdirectory(folder);
}
type type = typeof(t);
if (string.isnullorempty(this.dbfile))
{ this.dbfile = path.combine(folder, type.name + ".xml"); }
}
catch (exception ex)
{
console.writeline(ex.message);
}
}
public static xmlserializerbll<t> getinstance()
{
if (instance == null)
{
instance = new xmlserializerbll<t>();
}
return instance;
}
public void insert(t entity)
{
this.entitylist.add(entity);
this.writedb();
}
public void insertrange(ilist<t> list)
{
this.entitylist.addrange(list);
this.writedb();
}
public system.collections.generic.list<t> selectby(string name, object value)
{
system.collections.generic.list<t> list = new list<t>();
if (value == null)
{
return list;
}
type t = typeof(t);
foreach (var inst in this.entitylist)
{
foreach (propertyinfo pro in t.getproperties())
{
if (pro.name.tolower() == name.tolower())
{
if (value.tostring() == (pro.getvalue(inst, null) ?? string.empty).tostring())
{
list.add(inst);
}
}
}
}
return list;
}
public t selectbyid(string id)
{
type t = typeof(t);
foreach (var inst in this.entitylist)
{
foreach (propertyinfo pro in t.getproperties())
{
if (pro.name.tolower() == "id")
{
if (id == (pro.getvalue(inst, null) ?? string.empty).tostring())
{
return inst;
}
}
}
}
return default(t);
}
public void updatebyid(t entity)
{
type t = typeof(t);
string id = string.empty;
foreach (propertyinfo pro in t.getproperties())
{
if (pro.name.tolower() == "id")
{
id = (pro.getvalue(entity, null) ?? string.empty).tostring();
break;
}
}
this.deletebyid(id);
this.insert(entity);
}
public void deletebyid(string id)
{
type t = typeof(t);
t entity = default(t);
foreach (var inst in this.entitylist)
{
foreach (propertyinfo pro in t.getproperties())
{
if (pro.name.tolower() == "id")
{
if ((pro.getvalue(inst, null) ?? string.empty).tostring() == id)
{
entity = inst;
goto finishloop;
}
}
}
}
finishloop:
this.entitylist.remove(entity);
this.writedb();
}
public list<t> selectall()
{
this.readdb();
return this.entitylist;
}
public void deleteall()
{
this.entitylist.clear();
this.writedb();
}
private void writedb()
{
xmlserializer ks = new xmlserializer(typeof(list<t>));
fileinfo fi = new fileinfo(this.dbfile);
var dir = fi.directory;
if (!dir.exists)
{
dir.create();
}
stream writer = new filestream(this.dbfile, filemode.create, fileaccess.readwrite);
ks.serialize(writer, this.entitylist);
writer.close();
}
private void readdb()
{
if (file.exists(this.dbfile))
{
xmlserializer ks = new xmlserializer(typeof(list<t>));
stream reader = new filestream(this.dbfile, filemode.open, fileaccess.readwrite);
this.entitylist = ks.deserialize(reader) as list<t>;
reader.close();
}
else
{
this.entitylist = new list<t>();
}
}
}
}
namespace wisdombud.xmldb
{
public class basexmlbll<t> where t : new()
{
public string dbfile
{
get { return this.bll.dbfile; }
set { bll.dbfile = value; }
}
private xmlserializerbll<t> bll = xmlserializerbll<t>.getinstance();
public void delete(string id)
{
var entity = this.select(id);
bll.deletebyid(id);
}
public void insert(t entity)
{
bll.insert(entity);
}
public void insert(list<t> list)
{
bll.insertrange(list);
}
public system.collections.generic.list<t> selectall()
{
return bll.selectall();
}
public void update(string oldid, t entity)
{
bll.updatebyid(entity);
}
public t select(string id)
{
return bll.selectbyid(id);
}
public system.collections.generic.list<t> selectby(string name, object value)
{
return bll.selectby(name, value);
}
public void deleteall()
{
bll.deleteall();
}
}
}
希望本文所述对大家的c#程序设计有所帮助。