• 分享Db4o的便捷封装类源码


    导言

    大家好,话说真是好久好久没写文章了,哈哈。

    最近在写网站,个人对传统数据库天然抵触,感觉非常繁冗,即便是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,真心的,桌面、网站、移动无往不利,你值得拥有。

  • 相关阅读:
    实现Android ListView 自动加载更多内容
    Android中通过GPS或NetWork获取当前位置的经纬度
    android检测当前网络是否可用
    怎么样获得泛型T的Class对象?
    slidemenu
    linux mysql 操作命令
    解决Skyline 6.5版本中3DML模型单体化后外部网页挂接问题
    解决Skyline6.5多球对比时,自动运行TerraExplorer软件的问题
    OSGeo.OGR.Geometry
    TerraExplorer Add-ons 和TEZ使用说明
  • 原文地址:https://www.cnblogs.com/SkyD/p/3574651.html
Copyright © 2020-2023  润新知