导言
大家好,话说真是好久好久没写文章了,哈哈。
最近在写网站,个人对传统数据库天然抵触,感觉非常繁冗,即便是Entity Framework也过于庞杂了,Db4o这种轻量级且读写、配置都极其方便的新型数据库非常适合我。
不过我发现Db4o这么多年发展下来,竟然仍旧没多少中文资料可寻,很奇怪为什么这么优秀的数据库国内使用率极低呢?于是我就想尝试自己来写一些心得什么的,为Db4o在国内的传播尽微薄之力吧。
此次分享的是自己写的工具类代码,封装了Db4o的一种基本使用方式,高度优化了调用体验,下面直接介绍用法,源代码在文章末尾贴出。
初始化
如果是桌面应用的话,那就在程序开始时直接初始化即可:
/// <summary> /// Db4o服务器管理器 /// </summary> public static Db4oServerManager Db4oServerManager=new Db4oServerManager("db.db4o");
如果是网站,建议在Global.asax里作为网站核心类的静态属性,并在网站启动时初始化:
public class MvcApplication : System.Web.HttpApplication { /// <summary> /// Db4o服务器管理器 /// </summary> public static Db4oServerManager Db4oServerManager; protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); Db4oServerManager = new Db4oServerManager(Server.MapPath(System.Configuration.ConfigurationManager.ConnectionStrings["db4o"].ConnectionString)); } public override void Dispose() { Db4oServerManager.Dispose(); base.Dispose(); } }
然后记得在Web.config里配置数据库存放路径:
<connectionStrings> <add name="db4o" connectionString="/App_Data/db.db4o"/> </connectionStrings>
调用方法
注:下文以网站项目为例
建议采用Lambda表达式方法调用:
//无返回值调用方法 MvcApplication.Db4oServerManager.Access(q => { //查找相同ID的对象,以进行更新,否则直接存储将存储为新对象 var u = q.Query<ApplicationUser>(t => t.Id == user.Id).First(); u.用户信息.名称 = model.DisplayName; //必须明确存储子对象才能得到正确更新,因为默认貌似没有开启级联更新(新建对象存储时会默认自动存储子对象,但更新对象时不会自动更新子对象) q.Store(u.用户信息); });
//有返回值调用方法 return MvcApplication.Db4oServerManager.AccessAndReturn(q => q.Query<WebSite.Models.ApplicationUser>(t => t.UserName == User.Identity.GetUserName()).First().用户信息.名称)
下面是传统一些的调用方式:
using (var dbsa = MvcApplication.Db4oServerManager.CreatAccessor()) { var finduser = dbsa.Query<TUser>(q => q.Id == user.Id).FirstOrDefault(); dbsa.Delete(finduser); }
源代码
/// <summary> /// Db4o服务器访问器。注意,对数据进行修改后必须释放此对象才能真正的将更改提交到服务器。建议配合using(var dbsa=new Db4oServerAccessor(...)){...}语句使用 /// </summary> // ReSharper disable once InconsistentNaming public class Db4oServerAccessor : IDisposable { // ReSharper disable once InconsistentNaming private IObjectContainer DBContainer { get; set; } /// <summary> /// 构造函数 /// </summary> /// <param name="serverManager">Db4o服务器管理器</param> public Db4oServerAccessor(Db4oServerManager serverManager) { DBContainer = serverManager.OpenClient(); } public void Store(object o) { DBContainer.Store(o); } public IDb4oLinqQuery<T> Query<T>(Predicate<T> p) { return from T q in DBContainer where p(q) select q; } public IDb4oLinqQuery<T> QueryAll<T>() { return from T q in DBContainer select q; } public int Count<T>(IDb4oLinqQuery<T> collection) { return collection.Count(); } public int CountAll<T>() { return QueryAll<T>().Count(); } public int Count<T>(Predicate<T> p) { return Query(p).Count(); } public int CountAllByExt<T>() { foreach (var storedClass in DBContainer.Ext().StoredClasses()) { if (storedClass.GetName() == typeof(T).FullName) return storedClass.InstanceCount(); } return 0; } public void Delete(object o) { DBContainer.Delete(o); } public void Delete<T>(Predicate<T> p) { foreach (var f in Query<T>(p)) { Delete(f); } } #region IDisposable 成员 public void Dispose() { DBContainer.Dispose(); } #endregion }
/// <summary> /// Db4o服务器管理器 /// </summary> // ReSharper disable once InconsistentNaming public class Db4oServerManager : IDisposable { private IObjectServer _db4OServer; private readonly string _dbFilePath; /// <summary> /// 构造函数 /// </summary> /// <param name="dbFilePath">数据库文件路径,通常使用Server.MapPath("/xxxx/xx.xx")函数获取到。</param> public Db4oServerManager(string dbFilePath) { _dbFilePath = dbFilePath; OpenServer(); } private void OpenServer() { IServerConfiguration serverConfig = Db4oClientServer.NewServerConfiguration(); _db4OServer = Db4oClientServer.OpenServer(serverConfig, _dbFilePath, 0); } /// <summary> /// 开启一个客户端实例 /// </summary> /// <returns>客户端实例</returns> public IObjectContainer OpenClient() { Begin: try { return _db4OServer.OpenClient(); } catch { OpenServer(); goto Begin; } } /// <summary> /// 创建一个服务器访问器对象。注意,对数据进行修改后必须释放此对象才能真正的将更改提交到服务器。 /// </summary> /// <returns>一个服务器访问器对象</returns> public Db4oServerAccessor CreatAccessor() { return new Db4oServerAccessor(this); } /// <summary> /// 创建并访问一个服务器访问器对象。 /// </summary> /// <param name="action">对服务器访问器对象的操作行为</param> public void Access(Action<Db4oServerAccessor> action) { using (var dba = CreatAccessor()) { action(dba); } } /// <summary> /// 创建并访问一个服务器访问器对象,继而获得返回值。 /// </summary> /// <param name="action">对服务器访问器对象的操作行为</param> /// <typeparam name="T">返回值类型</typeparam> public T AccessAndReturn<T>(Func<Db4oServerAccessor,T> action) { T v = default(T); using (var dba = CreatAccessor()) { v= action(dba); //System.Diagnostics.Debug.WriteLine(v.ToString()); } return v; } #region IDisposable 成员 public void Dispose() { _db4OServer.Dispose(); } #endregion }
结语
最后容我再郑重向大家强力推荐一下Db4o,真心的,桌面、网站、移动无往不利,你值得拥有。
注意:此博客已停止更新,并迁移至blog.SkyDev.cc,后续都将在新地址更新。
转载请遵循此协议:署名 - 非商业用途 - 保持一致
并保留此链接:http://skyd.cnblogs.com/