简单的xml数据库设计

有时候系统需要存储一些简单的关系型属性,不考虑并发,不考虑性能(一次操作在几ms),数据库没有其他依赖引用,拿过来就可以用

为什么选xml作为数据库?

可读性好

实体的对应关系不严格

二进制序列化实体改动后不能读取以前序列化的数据,而且实体上面需要贴可序列化标签

数据库功能

无侵入存储实体,可存储poco对象,不需要在实体上面贴标签或继承什么

单例操作内存数据,只有初始化或者写入的时候才会读写文件,其他时候操作内存中的数据

使用指南 * 定义实体(public) public class Friend{} * 定义实体操作类,继承XmlDb<T> public class FriendDbSet : XmlDb<Friend> { static FriendDbSet _instance = new FriendDbSet(); public static FriendDbSet GetInstance() { return _instance; } } * 操作实体 Friend friend = new Friend() { Id = "1", name = "何仙姑" }; Friend friend2 = new Friend() { Id = "1", name = "何仙姑2" }; //添加 FriendDbSet.GetInstance().Add(friend2); //删除 FriendDbSet.GetInstance().Remove(r => r.Id == "1"); //修改 friend.name = "何惠惠"; FriendDbSet.GetInstance().UpdateByIdOrKey(friend); //查询 var result = FriendDbSet.GetInstance().ToList().Where(r => r.name.StartsWith("何")); >也可以不定义实体操作类直接进行如下操作 >XmlDb<Friend>.GetInstance().Add(u);//增加 >XmlDb<Friend>.GetInstance().Remove(r=>r.Age>1000);//根据条件删除 >XmlDb<Friend>.GetInstance().Remove("key");//根据key或id删除 >XmlDb<Friend>.GetInstance().UpdateByIdOrKey(new User() { });//修改 >XmlDb<Friend>.GetInstance().ToList();//查询全部 >XmlDb<Friend>.GetInstance().Find("key");//查询单个 代码(使用单例模式,模版方法模式)

public class XmlDb where T : new()
{
private static XmlDb instance = new XmlDb();

public static XmlDb<T> GetInstance() { return instance; } private List<T> entityList = new List<T>(); public XmlDb() { this.SetDbFile(); this.ReadDb(); } private string dbFile; private string Dbfile { get { return dbFile; } set { if (!string.IsNullOrEmpty(value) && !value.Equals(dbFile)) { this.entityList.Clear(); } dbFile = value; this.ReadDb(); } } protected virtual 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>(); } } protected virtual void SetDbFile() { string folder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "storage", "litedb"); if (!Directory.Exists(folder)) Directory.CreateDirectory(folder); Type type = typeof(T); if (string.IsNullOrEmpty(this.Dbfile)) { //获取全名称签名,防止类名重复 string md5Sign = BitConverter.ToString(MD5.Create().ComputeHash(System.Text.Encoding.UTF8.GetBytes(type.FullName))).Replace("-", ""); this.Dbfile = Path.Combine(folder, type.Name + "_" + md5Sign + ".xml"); } } protected virtual void WriteDb() { //异常处理 string tempFileName = this.dbFile.Replace(".xml", "_Temp.xml"); try { XmlSerializer ks = new XmlSerializer(typeof(List<T>)); FileInfo fi = new FileInfo(this.Dbfile); var dir = fi.Directory; if (!dir.Exists) { dir.Create(); } //缓存数据防止读写失败 if (fi.Exists) { fi.CopyTo(tempFileName, true); } Stream writer = new FileStream(this.Dbfile, FileMode.Create, FileAccess.ReadWrite); ks.Serialize(writer, this.entityList); writer.Close(); //删除缓存数据 if (File.Exists(tempFileName)) { File.Delete(tempFileName); } UpdateSchema(); } catch (Exception ex) { //恢复数据 throw ex; } } /// <summary> /// 更新数据的元数据信息 /// </summary> private void UpdateSchema() { string root = Path.GetDirectoryName(this.Dbfile); var files = Directory.GetFiles(root, "*.xml").Where(r => !r.EndsWith("schema.xml")).Select(r => Path.GetFileName(r)); //构建xml并存储 string schemaFile = Path.Combine(root, "schema.xml"); XDocument xdoc = new XDocument(); XElement xmlroot = new XElement("root"); xdoc.Add(xmlroot); foreach (var item in files) { xdoc.Root.Add(new XElement("fileName", item)); } xdoc.Save(schemaFile); } /// <summary> /// 根据主键或Id获取实体对象 /// </summary> /// <param></param> /// <returns></returns> public T Find(string KeyOrId) { Type t = typeof(T); foreach (var inst in this.entityList) { foreach (PropertyInfo pro in t.GetProperties()) { var keyattr = pro.GetCustomAttribute(typeof(System.ComponentModel.DataAnnotations.KeyAttribute), false); if (keyattr != null || pro.Name.ToLower() == "id") { if (pro.GetValue(inst, null)?.ToString() == KeyOrId) { return inst; } } } } return default(T); } public void Add(T entity) { this.entityList.Add(entity); this.WriteDb(); } public void AddRange(List<T> list) { this.entityList.AddRange(list); this.WriteDb(); } public List<T> ToList() { this.ReadDb(); return entityList; } /// <summary> /// 根据条件移除元素 /// </summary> /// <param></param> public void Remove(Predicate<T> filters) { this.entityList.RemoveAll(filters); this.WriteDb(); } /// <summary> /// 根据key或id移除元素 /// </summary> /// <param></param> public void Remove(string KeyOrId) { Type t = typeof(T); T entity = default(T); foreach (var inst in this.entityList) { foreach (PropertyInfo pro in t.GetProperties()) { var keyattr = pro.GetCustomAttribute(typeof(System.ComponentModel.DataAnnotations.KeyAttribute), false); if (keyattr != null || pro.Name.ToLower() == "id") { if (pro.GetValue(inst, null)?.ToString() == KeyOrId) { entity = inst; goto FinishLoop; } } } } FinishLoop: entityList.Remove(entity); this.WriteDb(); } public void UpdateByIdOrKey(T entity) { Type t = typeof(T); string id = string.Empty; foreach (PropertyInfo pro in t.GetProperties()) { var keyattr = pro.GetCustomAttribute(typeof(System.ComponentModel.DataAnnotations.KeyAttribute), false); if (keyattr != null || pro.Name.ToLower() == "id") { id = pro.GetValue(entity, null)?.ToString(); break; } } this.Remove(id); this.Add(entity); } /// <summary> /// 清空列表 /// </summary> /// <param></param> public void Clear() { entityList.Clear(); this.WriteDb(); } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzgdww.html