分享Db4o的便捷封裝類源碼

導言

你們好,話說真是很久很久沒寫文章了,哈哈。數據庫

最近在寫網站,我的對傳統數據庫自然抵觸,感受很是繁冗,即使是Entity Framework也過於龐雜了,Db4o這種輕量級且讀寫、配置都極其方便的新型數據庫很是適合我。服務器

不過我發現Db4o這麼多年發展下來,居然仍舊沒多少中文資料可尋,很奇怪爲何這麼優秀的數據庫國內使用率極低呢?因而我就想嘗試本身來寫一些心得什麼的,爲Db4o在國內的傳播盡微薄之力吧。ide

這次分享的是本身寫的工具類代碼,封裝了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>

調用方法

注:下文以網站項目爲例this

建議採用Lambda表達式方法調用:spa

                    //無返回值調用方法
                    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().用戶信息.名稱)

下面是傳統一些的調用方式:code

            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,真心的,桌面、網站、移動無往不利,你值得擁有。

相關文章
相關標籤/搜索