你們好,話說真是很久很久沒寫文章了,哈哈。數據庫
最近在寫網站,我的對傳統數據庫自然抵觸,感受很是繁冗,即使是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,真心的,桌面、網站、移動無往不利,你值得擁有。