下载地址:
http://www.netfocus.cn/downloaddetail10387.html简要说明:
学习了著名开源社区CommunityServer(CS)的抽象数据库的设计,自己独立思考,站在哲学的角度上思考问题,并进一步抽象,最终设计出了一套非常抽象的通用数据库以及通用数据访问层。
主要有以下优点:
1)通过两个抽象表存放任何数据实体以及实体之间的关系;
2)通过两种扩展字段设计方式实现任何数据实体的字段扩展需要,并且扩展的字段支持数据库级别的排序搜索功能;扩展字段的添加和一般字段没有什么大的区别,仅仅只是添加了一个特性而已。
3)由于将实体与实体之间的关系进行高度抽象(最终抽象为横向和父子递归两种关系),导致数据库访问层的接口的通用型非常广泛,可以适应任何实体之间的关系。这样的设计用一般的言语无法表达;也许你看了代码之后会有所体会;
4)吸取了CS中的很多好的设计,如Provider模式,动态构建SQL实现自定义查询,缓存,多语言资源文件设计,自定义Url重写,Ajax功能,etc.
5)目前该框架还在不断完善优化中。。 

解决方案 »

  1.   

    下载地址中包括源代码及Demo,运行步骤见readme.txt
      

  2.   

    分享技术我非常赞赏,而且分享做得好且稳妥,相比只是自己在自己的项目中用,将来一定可以获得非常丰厚的回报。不过,作出的东西一定要重视性能对比。实际上好的东西不但大大提高使用他进行设计的速度,也应该有不低的运行性能。如果运行性能差很多(例如只有较低级开发方法原来的70%)就会阻碍别人使用它。在保持接口不变的前提下,性能测试要求往往会让你做出更重大的结构调整,所以我建议你你要尽早考虑到这些,不要设计得过分理想,对于适合哪些不适合哪些都要做一些自动化测试然后给出结论。例如,如果一个ORM做的很好,即使完全地读写整个对象的所有属性,也可以做到比直接使用SQL读取部分某个表中记录的字段的速度不差。并且复杂的涉及多表、大量数据关联查询的速度也不慢。如果有可能,应该支持Linq并且可以编译为底层数据库的原生查询命令去查询(而不是在查询组件中去计算)。总之,使用十万个对象进行大量测试(至少写上十几个测试用例),分别对新增、更新、查询、关联、事务等多种操作考察其稳定性和速度,拿出测试数据来心理才真正有底。如果只是一个技术原型,只有刚刚实现了功能的代码但是没有专门测试这些功能的代码,心里的底气不足。
      

  3.   

    这里我贴一小段我在为某种底层数据库实现了通用的引擎接口功能之后的最初的几个测试代码:using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading;
    using Domain;
    using Wuwei.ORM.Test;namespace TestDomain
    {
        class Program
        {        static List<HasA> TestDatas = new List<HasA>();        static void Main(string[] args)
            {
                var s = Rnd.Next().ToString();
                TestDatas.Add(new HasA() { Parent = s, Child = 2008 });
                TestDatas.Add(new HasA() { Parent = s, Child = 2009 });
                TestDatas.Add(new HasA() { Parent = "hello", Child = "world" });
                using (var db = new Client())
                {
                    TestDatas.ForEach(d => db.Save(d));
                    db.Commit();
                }
                new TestRunner().ConsoleStart();            //开始通过测试引擎驱动这些测试
            }        class Test1Class
            {
                public int X;
            }        [RunTest("测试Domain可以创建数据库文件。启动测试前请删除旧的数据库文件。", "08/8/20 7:00")]
            static void Test1()
            {
                using (var d = new Client())
                {
                    d.Save(new Test1Class { X = 1234 });
                    d.Commit();
                    "数据库文件不存在。".ThrowOutIf(() => !d.File.Exists);
                }
                using (var d = new Client())
                {
                    "打开的数据库文件错误,或者保存对象错误。".ThrowOutIf(() => !d.Cast<Test1Class>().Any(a => a.X == 1234));
                }
            }        static Random Rnd = new Random();        [RunTest("测试HasA可以保存,以及自动Rollback机制。", "08/8/20 7:20")]
            static void Test2()
            {
                var s = Rnd.Next().ToString();
                Client.ToDo(d =>
                {
                    var m = new HasA() { Parent = s, Child = 123 };
                    d.Save(m);
                    d.Commit();
                    m.Parent = s + s;
                    d.Save(m);     //测试随后(没有commit语句因此)自动rollback可以回滚数据。
                });
                Client.ToDo(d =>
                {
                    var ts = "123443434";
                    var f = from HasA x in d where x.Parent.Equals(ts) select x;
                    ts = s;
                    " HasA无法保存或者冗余保存。".ThrowOutIf(() => f.Count() != 1);
                });
            }
            [RunTest("测试10个Client线程并行查询数据库,结果完全一致。", "08/8/31 2:40")]
            static void Test5()
            {
                var result = new List<int>();
                var s = Rnd.Next().ToString();
                1.ForEachNumTo(10, i =>
                {
                    ThreadPool.QueueUserWorkItem(x =>
                    {
                        using (var d = new Domain.Client())
                        {
                            var f = from HasA h in d where h.Parent == Program.TestDatas[1].Parent select h;
                            result.Add(f.Count());
                        }
                    });
                });
                while (result.Count() < 10)
                {
                    Thread.Sleep(1);
                }
                var value = result[1];
                "并行查询出错。".ThrowOutIf(() => result.Any(x => x != value));
            }
    在一个简单的测试程序驱动下,它会去寻找所有的这些测试程序(大型系统往往可以有上千个测试),并且(只要我没有中断它)会成千上次地随机执行测试。开源软件要比那些用钱堆出来的软件项目更应该重视自动化测试。
      

  4.   

    向牛人学习。
    UP。
    JF。
      

  5.   

    下一代的数据库??? 比起SQLSERVER,MYSQL, 有什么新的概念吗?
      

  6.   


    呵呵,你可以事后才补充测试,也可以事前就开始测试,从前一种变为后一种开放方法其实对探索性的项目的开发至关重要的。我很熟悉vs上的 Ctrl+K+M 快捷功能——自动生成方法存根。当我不过度技术化的时候(而是紧贴目标去开发的时候),我会先设计接口,然后就开始写测试程序,测试程序中自然要new被测试对象,写好代码后我都习惯了“F5”,此时肯定编译通不过,因为这个被测试对象根本没有实现,这就是我开发的启动动作。如果事后再做测试,你几乎无法真正做全面的功能测试,只能做几个简单的测试了事。很难有人会愿意在写完全部实现代码之后才去怀疑自己的代码的。只有TDD观念才能最好地保证产品质量。
      

  7.   

    是的,现在的我确实没有多大的怀疑自己的代码有什么大问题,但是对于性能问题,如何提高性能,以及如何处理异常,我还是会花大力气去探索的.功能方面我应该不会去花大力气研究是否正确,我希望可以在我以后的项目中不断实践不断发现Bug,不断完善提高.
      

  8.   

    楼主确实不错,通过学习这种著名开源社区CommunityServer(CS)的结构,很有感悟。
      

  9.   

    up
    sp1234说的太对了
    两年前考软设的时候接触过不少这样的理论性的东西
    不过两年的工作过程中从没接触过这样做的人
    哎~~
      

  10.   

    由于原先的设计有很大性能问题,经过几天努力,终于在性能方面提高了很多。
    另外,相对于之前的版本Demo的功能以及框架本身的设计方面都有了很大的改善,欢迎大家来下载使用。