明天就要大过年了,今天还在公司上班,闲着没事,在这里说下自己的心得.
  如果你还是一名菜鸟,或者你才接触程序不久,我建议你看下去.
  对于程序员来说,不论你采用何种语言,那都是次要的,不论你开发的是桌面应用程序还是WEB应用程序,那也是次要的,好的思想胜于具体的语言,好的程序架构胜于具体的运用类型,所以编程方面,没有什么最好或者最差的编程语言,不要认为你是学习Java的,你就认为.NET如何如何不好,也不要因为自己是.NET的拥戴者,你就嘲讽Java的如何如何,这个世界,没有什么事情是绝对的,如果你硬要说绝对的化,那么唯一的绝对,那就是每个人都会死.(别钻牛角尖了,这里不是想讨论这个,分享经验和思想而已)每种语言都有自己的特性和优劣,根据具体情况做选择,才是一名优秀的程序员才应该具备的.也不要因为你喜欢开发桌面应用程序,而嫌弃WEB应用程序如何如何,更不要因为你是开发WEB应用的,就喜欢说桌面又如何如何,桌面和WEB又有什么不同呢?我不知道各位是怎么想的,各位处在何种境界考虑这个问题.就我而言,以程序的分析方法来说,程序就是一个抽象类,然后从这个抽象类从派生处了具体的应用程序类型,所以不论是WEB还是桌面,乃至是PDA以及手机,开发思想都是一样的,运用良好的分层框架设计,一套代码,可以运用在许多种类型的运用程序上,所以现在的程序没必要分的那么严格了.
  再来就是说下理论与实践吧,我不知道大家这么看待这个问题,我教导的一位朋友(现在还在读大学,今年毕业).和他说到这个的时候,他跟我说,他还是喜欢多练习,练习多了.他自然就会了,关于理论什么的,那些太模糊了,不如实践更容易理解.还有我曾经帮助的一位厦门大学的朋友.她曾经问过我许多问题,我都给了她解决方案,并接从原理到步骤中进行了详细分析.她问我写了多少程序,我说我没写多少,只看数.她居然说不实践成长不了的.我当时觉得很可笑吧.但是没说什么,对于任何事情来说,实践固然重要,也应该是非常重要的.但是理论更加的重要,好的实践的基础离不开坚实的理论基础,试想下,我是没亲自去敲代码,但是如果我能把一个程序,从开始运行到最后结束,每行代码都说出来,你认为我能不能写出这个程序了.实践不能让你的水平有所提高的,它所提高的只是你的开发效率,以及记忆程度,如果你提高技术能力,理论还是绝对重要的.不要给自己找理由,强化理论基础,加强使用技巧经验才是王道.
  再者就是开发观念,建议明白下你所使用的语言究竟是什么语言,不要自己认为自己懂的,我曾经看到过许多团队的开发人员,使用.NET开发网站,那代码真的写的让我佩服的想哭了.烂的可以了,不要因为你使用的是面向对象语言,你就认为自己是在做面向对象设计与开发了,这种思想是极度错误的.关于面向对象的三大特性:继承,,封装,多态.你自己好好问下你自己,你究竟了解多少,你在实际中又就将考虑了多少.面向对象的三大特性,使用起来确实不会让你的程序书写起来更加的容易,它可能使你原来很简单的一个程序难度提高2-10倍,甚至更多,但是这种设计上的付出,收获也是巨大的.关于这三个特性,最好的组合就是设计模式的运用,良好的设计模式的使用使得写出来的代码优美,可复用性高,易扩展.对于设计模式,也别觉得有什么困难的,所谓的设计模式也就是一种开发思想而已,很简单,记住良好的软件的5大原则:单一职责原则,开闭原则,依赖倒转原则等,再配合已经存在的23种设计模式,根据具体情况分析选择设计,举一反三就可以了.不要因为这样麻烦,就不这么去考虑问题,如果你只想继续当菜鸟,那我没什么好说的.毕竟各人追求不同.我记得曾经面试一个公司,我带这自己的作品去面试,看了一眼他们的软件开发代码,我无语了,面向过程开发用的好熟练,程序员的CV功夫也运用的很熟练,后来我再介绍自己的代码的时候,结果批评了他们那么做的缺点(结果不用说你们都知道了,当然是没戏了,但是不管怎么样,提高自己的技术修养和思想还是蛮重要的)。
  2009年会如何,很难说,但是可以肯定的一点就是,我会成功的转型为一名软件架构师。在这里献上自己的点点看法和心的。其他的就不多废话了,毕竟每个人的看法都不一样,我也无法明白别人怎么定位,但是我知道自己对自己的要求,理论越强大,思考的越多,看到的方法越多,所能想到的解决方案也就越多。也就越接近更高的境界了。最后我分享下自己认为的最好的数据库辅助类的写法。(如果大家有什么更好的方法,欢迎跟帖。对于学习,我时刻都在更新自己的经验和技术)1 对于实际开发而言,一般都会写一个数据库的访问类。(注:这个数据库访问类不是数据访问层哦,而是基本的数据访问方法)
   大家都知道ADO.NET为开发认为提供了4种的提供程序,分贝是MS SQL, OLE DB...等。然而在大多数情况下许多开发人员都喜欢在只写定一种,其实这样设计的代码可复用性很地的。如下:
public staitc class DataAccess
{
    private static readonly string _ConnectionString; //数据库的连接字符串    static DataAccess()
    {
        _ConnectionString = ConfigurationManager.ConnectionStrings["Config"].ConnectionString;
    }    public static SqlCommand CreateCommand()
    {
        SqlConnection connection = new SqlConnection(_ConnectionString);
        return connection.CreateCommand();
    }    public static DataTable ExecuteCommand(SqlCommand command)
    {
        DataTable table = null;        try
        {
            command.Connection.Open();
            SqlDataReader read = command.ExecuteReader();
            table.Load(read);
            read.Close();
        }
        finally
        {
            command.Connection.Close();
        }        return table;
    }    ///...下面更多的方法省略
}这么写的化,我们不能说写错了,但是这么写,如果数据库改成MySQL或者别的什么了,那么我们就必须为新的程序再写一套程序代码。这样子程序的复用性就显得非常的低,大家要明白,ADO.NET为我们提供了一套统一的编程模型,这个时候我们可以考虑使用设计模式,借助类的三大特性来改写下以上的代码,这样子,我们的程序就更容易适应变化了,改写的代码如下:
public class DataAccess
{
    private static readonly string _ConnectionString;
    private static readonly string _ProviderName;    static DataAccess()
    {
        _ConnectionString = ConfigurationManager.ConnectionStrings["Config"].ConnectionString;
        _ProviderName = ConfigurationManager.ConnectionStrings["Config"].ProviderName;
    }    public static DbCommand CreateCommand()
    {
        //利用抽象工厂模式来声场具体的提供程序生成工厂类
        DbProviderFactory factory = DbProviderFactories.GetFactory(_ProviderName);
        //利用具体的提供程序工厂生成对象生成具体的对象
        DbConnection connection = factory.CreateConnection();
        return connection.CreateCommand();
    }    public static DataTable ExecuteCommand(DbCommand command)
    {
        DataTable table = null;        try
        {
            command.Connection.Open();
            DbDataReader read = command.ExecuteReader();
            table.Load(read);
            read.Close();
        }
        finally
        {
            command.Connection.Close();
        }        return table;
    }    ///...下面更多的方法省略
}
以上合理的运用设计模式,借助继承和多态来实现,这样子在以后即使数据库变了,我们只需要修改下配置文件就可以了,代码的重用能力得到的很大的提高。关于那两个工厂类,大家完全不需要自己实现了,NET中已经为我们提供了这两个类,但是想要弄清楚这两个类的实现原理,就必须明白类的继承和多态以及工厂模式,在这里。我就不具体分析了。因为实践的关系,更详细的写法,我没有写出来,只做一个介绍,大家自己扩展。如果各位有更好的方法,希望交流,我掌握的还是蛮多和精炼的,欢迎赐教和讨论。

解决方案 »

  1.   

    还年轻啊,都25了.不过各人追求不一样,今年转架构师是肯定的,这方面的知识在加强努力中,这方面的著作和经验理论也不断强化中,技术好像没必要再去强化了,至少最近一年没必要了,新技术NET3.5的WPF,SL2,WCF,以及SSH框架那些都运用自如了,所以还是研究框架设计的经验和理论,明年一定要当框架师,这样菜符合我的成长计划。人要有追求嘛。我还是蛮相信自己的自学能力的,毕竟这么久来,我没参加任何培训,所进的公司,也没采用什么先进的开发思想,都是通过自己的思考和积累以及查书成长的。所以我相信自己可以的。
      

  2.   

    那么你认为你有更好的写法么?我还是蛮虚心请教的,在那里废话是没意义的,你如果有更好的方法,可以亮出来看看,在这里乱评价是没意义的,如果你想比技术,我也觉得没必要了,我还是蛮全才的,现在流行的三大语言C++,C#,Java以及他们相关的类库MFC,SSH,.NET还有最新的技术WCP WPF SL我都熟练运用,设计模式,我也精通,大师不敢称,专家有又什么不可呢?所以嘛和你吵没意义的,有更好的代码,我欢迎。没有的话,就别乱评论了。程序员还是靠技术的。不是靠嘴的。
      

  3.   

    帮我解释一下接口和抽象类的区别,我一直理解不好?
    还有不同线程是如何访问你代码里面的static函数的,我想了很久?
    没办法我讨厌“专家”,因为我还是菜鸟
      

  4.   

    不同线程访问STATIC函数你就这样理解了.每一个线程调用时都会有自己的堆栈空间
      

  5.   


    难道_ConnectionString变量是摆设?
      

  6.   

    专业的术语解释不易于理解,就说白点吧,其实抽象类和接口没有太大的区别,不论是抽象类还是使用接口,在该类型进行实例化的时候,该接口或对象实际上就是所new的那种类型,只是因为声明的是接口或者抽象类的缘故,我们只能使用该接口或者抽象类中所声明的同名方法。在区别上,类在新的语言中,已经没办法进行多继承了,而接口可以,并且对于继承而言,如果一个类继承一个抽象类,那么这个类可以选择是否实现这个抽象类中所定义的抽象方法,如果不实现,那么程序一样可以继续编译,并且该类还是以抽象类的形式实现,但是对于接口而言,继承(更确切的说法是实现),实现该接口的类必须实现该接口所包含的方法,即使是空方法,所以说接口和抽象类其实区别也不是很大,但是抽象类在描述对象的时候,我们更加确切,比如动物类,如果用动物接口,也不能说你错了,但是这么一来,形象上也可以实现功能,但是理解上就怪怪的。毕竟多态还是以重写父类的方法的形式来实现的,所以抽象类在这个时候使用更加的符合实际
      

  7.   


    那像楼主一样,都static算了
      

  8.   

    别找碴了,笔误,Ok
    _ConnectionString那步笔误没写上去,OK.
    你这种人蛮无聊的,说了,如果你有好的方法,我欢迎,毕竟这种写法,我还是从美国的一位大师级别的人那些学习来的。然后转化成我自己的经验,我说了,这样写DBHELER类是我暂时见过的最好的写法,你如果真有,我虚心请教,如果没有,就分享经验,有能力的化,我不会认为你自大,但是如果没能力,还这样的化,那很容易给人看不其的。
      

  9.   

    好像确实是这样...
    不过有人说全部STATIC不OO所以有时用实例的.我看我们同事写的代码是全STATIC的你不说我倒想不起来
      

  10.   

    跟不懂又喜欢自大的人解释技术没意义,连为什么用static都没办法看出来,我也就没必要解释了,不告诉你的原因不是因为看不起你,而是你的态度差劲的没必要回答你的问题。找碴的话。随便,反正我确实是学习的很精通了,又不会因为你说什么我就变菜了,我可没你那么小心眼,作为程序员,不服气的话,就努力到超越为止,光靠嘴来,能进步么?我蛮不喜欢这类人的,而且这类人在中国程序界还算大多数,想象我学习的时候,每天从早到黑的看电子书,跑书店,那上过论坛问过问题,也不和别人斗嘴,和新人斗,有意义么?和老手斗,你又太菜。自我鼓励就好了。不行就努力到行不就好了,嫉妒干嘛。也没必要羡慕。唉,不和你吵闹,和大家分享经验,表达自己的个人看法而已,你是否进步,是你自己的事,反正我还是要进步的,这样才我才更愉快。还是哪句话,程序员不是靠嘴的,技术才是最重要的。多努力学习,超越别人,才是最正确的。别想着别人给你太多的帮助,还是靠自己吧。
      

  11.   

    其实吧,我见过很多公司的DB封装类,然后调用的时候都这么写
    try
    {
       Utility.getConnection();
       ......
       Utility.closeConnection();
    }
    catch
    ......再其实吧,我一直不太理解为什么非要封装一下呢?不好意思,以前一直写Java代码,最近一年不到才接触ASP.NET,从来没有写过一段完整的.NET代码,所以请教一些愚蠢的问题了,呵呵。
      

  12.   

    不是不太好,是极其不好,最后导致整个网站hang住了,呵呵。
      

  13.   


    在这里和你说下三大特性的封装吧。放心,我不会以专业的角度去解释这些技术问题,这样不易于理解,所谓封装,你可以这么理解,你是否记得你自己在写Java代码或者.NET程序的时候,经常使用它们提供的类库呢?一定有的,对吧,那么你又是否明白它们所提供的类库是怎么实现的呢?如果你不看源代码的话,你或许不知道,又或许自己能想到,但是你在进行开发的时候,你又有多少次去去考虑那个类是如何实现的呢?那底层的原理又是如何.就拿最简单的WriteLine而言,又有几个程序员使用了这么久的.NET类库,去研究过底层是如何实现的,包括我自己也没有去研究.所以嘛,所谓的封装,其实是针对其他人而言,而不是针对开发这个程序的程序员而言的,如果你自己都不知道你自己要开发什么,那么你还怎么去写这个程序,这样的好处在于,使用你这个类的人员,只用知道你所写的类提供什么功能就可以了,他们也就没必要去细究你的代码是如何实现的.是他们更加专注于自己要实现的功能,因为他们知道,只要使用你所写的这个类的那个功能,就能达到他们预期的效果.并且良好的封装,也能更好的保护数据安全性等.
      

  14.   

    大哥,继续找碴,我拥戴你可以了吧。估计你是火星的,火星的技术高,地球人比不过。不和你争辩,都说了,你不会明白理论代表什么,理论代表的不光是技术原理,还代表了使用经验。一句话,你把电脑敲烂了,写HELLO WORLD!到死,你也是菜鸟,因为从那种实践种,你学不到任何的理论经验,你的技术也没办法有可能提高的,你最多也就是比我敲HELLO WORLD速度快点罢了。
      

  15.   

    哈哈,谢谢阿。其实我想问的是为什么对DB操作进行封装呢?就好比你想得到SqlCommand,那么直接从connection得到好了,为什么非得调用你的类呢?除非说你自己内部还作了些处理,比如对连接池的管理,对连接的生命周期的管理(connection被使用完之后自动对其close)等等。
    请帮忙解释一下,谢谢。
      

  16.   


    说实话吧,就你写的那一小段代码而言,我没看出来能复用出什么结果来。每次执行一条SQL语句都要先打开一个连接,再关闭。如果我有多条SQL语句要执行的话,频繁开关连接是一种可取的策略吗?或者是大家都认为一个连接不适宜执行多条SQL呢?还有你提到的“不要让同样的代码重复两次”的规则我也不敢苟同,如果只有几行代码的量,重复两三次又有何不可?函数的调用开销也是不小的。其实,我确实真的想知道封装DB操作的好处究竟有哪些?而不是你所说的复用不复用的概念。
      

  17.   

    回 41 楼
    我不知道你是否看过软件工程学方面的书,或者你又对ADO.NET知道了解到什么程序,不要让同样的代码重复两次,在许多软件工程学的著作中都有出现,如代码大全2以及人月神话。建议你去看下。
    至于你看不怎么复用,那么建议你在写代码的时候,以后每次都在各个需要的地方写连接数据库的那些代码,等写多了,你就能明白这个问题了。
    ADO.NET很强大,你有这些疑问,是因为你对ADO.NET还没完全弄明白。建议去看MS处的ADO.NET技术内幕,网上可以下到电子版。
    还有什么疑问?
      

  18.   

    封装DB时,不要把connection封装进去,以参数的方式传进去。
    connection分开封装,利用工厂模式
      

  19.   

    http://msdn.microsoft.com/zh-cn/library/system.data.common.dbproviderfactory_methods.aspx
      

  20.   


    其实我对ADO.NET确实是菜鸟,只不过你那样子封装使用起来确实非常不方便。
    1. 无法操作到connection对象
    2. 要做transaction怎么办?
    3. 你用到了DataReader,如果我要用DataSet怎么办?
    ......请解惑,谢谢!
      

  21.   

    LZ的想法是对的。。但是不是这样设计的。。正如41楼所说。。我觉得LZ可能看了设计模式的书,诗性而发上来发个贴。
    而我设计的是数据层的访问抽象工厂,不知道LZ写的什么工厂。。
      

  22.   


    其实我对ADO.NET确实是菜鸟,只不过你那样子封装使用起来确实非常不方便。 
    1. 无法操作到connection对象 
    2. 要做transaction怎么办? 
    3. 你用到了DataReader,如果我要用DataSet怎么办? 
    ...... 请解惑,谢谢!回复
    1 如果要访问connection对象,直接使用command对象的connection书香就可以了。
    2 请看清楚我最后的一句话,时间的缘故,我没有把这个类的其他方法都写出来。都写完的化,当然有特别针对事务的方法  了。
    3 同上明白了么?
      

  23.   

    回复 56 楼LZ的想法是对的。。但是不是这样设计的。。正如41楼所说。。我觉得LZ可能看了设计模式的书,诗性而发上来发个贴。 
    而我设计的是数据层的访问抽象工厂,不知道LZ写的什么工厂。。第一,请你先明白分层的概念,数据访问层和数据库访问类是两个概念。
    第二,这种写法使得你没必要为不同的数据库而写不同的数据库访问对象了,就这一套代码,就可以得到4种类型的访问对象。代码的灵活性比那样写要多了许多。
    第三,有没有看到我最后说的,哪两个数据库提供程序的类.NET已经帮我们实现了。我们没必要自己再去实现了,如果你不清楚,建议你多看下MSDN。方法还是需要总结的,我的脑子离保存着我认为最好的方法,如果有更好的,我就会更新掉。这样学习才会有进步。
      

  24.   

    回复 57 楼老大,北大青鸟的视频,我也看过,那种写法那和这种写法一样,你仔细再看看视频,
    他的写法是
    public SqlConnection GetConnetion()
    {
      return new SqlConnection();
    }他是这么写的,和我的怎么一样呢?对吧。仔细看下视频,你就发现不同了,认真点学习嘛。
    你这个错误就和我一个朋友一样,看过我给他讲解了工厂模式,从他同学那里拷了份代码来,写的也是我的列子,
    稀里糊涂就认为是用工厂模式了,然后弄的我又重新讲解给他听。
      

  25.   

    其实我有时候也想发布篇我对C#,或者说.NET,不应该是微软的架构,未来10年的展望,但我还是有自知之明我看楼主属于从不会到入门了
      

  26.   


    从你的代码看来,你返回过来的command对象的connection属性还没有open呢,或者是已经关闭了(在你调用完ExecuteCommand之后)。
    算了,也不再跟你深究了,你始终觉得你封装得很好了。
      

  27.   

    回复 65 请问你 command.Connection.Open();  这句话你是否明白什么意思?你是否明属性代表着什么意思?
      

  28.   

    靠!我怒了!那到底是不是你自己写的代码阿?你不是在finally里面close了吗?
    姑且不论没有写catch是不是合法的(我不熟.NET)。
    但是你退出ExecuteCommand函数之后连接还能保持着阿?
      

  29.   

    回复 68朋友,你怒我也没办法。为这个问题发怒,不如弄明白属性的意义
    在Command对象中有一个私有的Connection引用
    与其相互关联的就是Connection属性
    通过该属性,我们可以访问该Command对象所使用到的连接对象的信息。
    你说你是在java转过来的
    比如说java里头
    public class Test
    {
     private String strA; public String GetStrA()
     {
       return strA;
     }
    }
    你会这么使用 new Test().GetStrA();
    那么在C#中,你为什么不能这样理解属性呢?原理都一样的,灵活运用嘛
    谁说ExcuteCommand后连接对象就关闭了?
    那本书上这么写的,告诉我。
    连接对象,你如果不显示关闭的话,就会一直打开。
      

  30.   


    楼主的代码command.Connection.Close(); 
    其实很明白。你为什么一定要“连接还能保持着”呢?
      

  31.   

    回复 70 楼
    Copy 你的么?我又不是你。
      

  32.   

    代码谁都看得很明白阿,就楼主没看明白,认为ExcuteCommand方法结束之后连接还保持在那里。
    那么这位老大,您可否跟我讲讲DB操作封装之后的其它好处?除了“复用”之外。
      

  33.   

    72 楼的大哥,你来搞定他吧。我是没办法继续解释了,ADO.NET 一看就完全不懂。而且自己问的问题也很模糊
    最主要的是问个问题还这么拽
    你是不是hibernate用多了,最基本的手写方式的jdbc使用方式都忘记了
    这个就与那个的基础思想一样嘛....
      

  34.   

    多谢两位老大赐教啊。
    说ADO.NET与JDBC的基础思想一样我又不敢苟同了,至少JDBC不会已经帮你封装好了ConnectionPool,所以做个DB封装类还是很有必要的。
    对于ADO.NET来讲,除了你调用的时候少写几行代码之外,究竟还能带来什么样的好处呢?请解惑,多谢了!提到Hibernate,我确实从03年就开始用了,再往前就只好自己写数据抽象层了。现在嘛,这些知识全都忘了。
      

  35.   

    其实要管理CONN,有别的方法,比如继承Dispose,LZ谈谈思想还行,数据访问帮助类也不是这样设计的,正如archu 所说,transaction,conn的问题.
    public class DbConn : IDisposable
    {
         //代码
    }
    #region IDisposable 成员public void Dispose()
    {
        if (_isConnection)
        {
    _connection.Dispose();
    _connection = null;
        }
        System.GC.SuppressFinalize(this);
    }#endregionusing (DbConn cm = new DbConn(new SqlConnection(ConnectionString)))
    {
    SqlConnection cn = (SqlConnection)cm.Connection;
            //代码
    }
      

  36.   

    回复 77 楼关闭了reader对象后,command对象所关联的connection对象并不会自动关闭
    除非在构建reader对象的时候,使用到了closeconnection行为。
    这样子在reader对象销毁的时候,连接对象也就会自动关闭。主要是他对这个也不明白。我怎么可能会没考虑到呢?
    毕竟想想当我第一次看到这样写的时候,我还花时间去研究了为什么这样写呢。
    分析之后,认为这样写确实是我暂时,只暂时ADO.NET最好的封装写法,所以
    就更新了以前的写法,一直到现在,如果有人能有更好的写法,我蛮愿意更新的。
      

  37.   

    为什么你死活看不到你自己写的这段代码呢?        finally
            {
                command.Connection.Close();
            } 
    承认你确实有几把刷子,所以才跟你讨论讨论。其实我主要想表达的意思是ASP.NET已经封装得很好了,我们再给他封装一层的意义究竟在哪里呢?除了你说的“复用”之外。
      

  38.   

    继续回复 81 楼
    老大,你有必要这么干么?
    DBConnection 是所有具体的Connection的父类,
    已经倍微软实现了,你还有必要自己这么写么?
    你这样和重复制造轮子有什么区别?
    不要看MSDN的时候,就只知道SQLconnection 以及 Ole dbconnection那及个嘛?
    多熟悉下msdn嘛
    先仔细分析下我发出的这样写法的思想是什么。再发表评价。OK?
      

  39.   

    command.Connection.close()反正还有半个小时,给你分析吧下吧。为什么写这个类,回答是 提高开发效率,程序中要访问数据库的地方很多,不可能在每个要访问数据库的地方,我都将整个ADO.NET的写法都重新写一次,所以封装成一个数据库辅助类。明白?首先你是否真的明白了 command 对象究竟是什么对象  command 的类型是DbCommand类型,知道么?它是ADO.NET的4种具体Command类型的抽象父类。
    这里利用到的是多态,你明白么?
    谁和你说了,我这里用到了自己多余的封装了。你只看市面上的书,怎么可能能发现有DbCommand类存在。
      

  40.   

    专家!public class DbConn : IDisposable,知道这个类的含义吗?其实没必要看全部,而你的代码没有可学习之处。
    我的访问类是通过DAC2架构写的。
      

  41.   

    我在finally中关闭连接对象,我怎么没看到呢?
    我又那里错了?
    看下82楼我的回复。
      

  42.   

    行,真是高人啊,原来此command非彼command也,那么command.Connection也必然是其它的Connection了,调用command.Connection.close()也就不是真的关闭ADO.NET里面的Connection了。所以呢,你的DataAccess类里面也必然有另外一个方法专门用来关闭Connection的,难道您这样的高人还能忘了关闭Connection吗?受教了!
      

  43.   

    回复 91 楼DbCommand command = DataAccess。CreateCommand();
    command。CommandText = sql;
    DataTable = table = DataAccess.ExecuteCommand(command);自己分析吧。你理解错误了,我根本就没重新封装connection对象。我早应该就看出来了
    我只是封装了ADO.NET的使用罢了,唉。早你上几个帖子中,我就应该看出来了
    如果到这种地步,你还不明白。那就搞笑了。
      

  44.   

    不好意思啊,早说了我是菜鸟了,见笑了!不过你怎么到现在才明白我在说你把那个Connection关闭的问题了呢?
      

  45.   

    你的 ExecuteCommand 将所有记录写入table变量返回,结束前及时地关闭了数据库连接(因为数据已经写入table,不需要连接了)。对于SQLServer等此command.Connection 连接就是具有缓冲池的逻辑连接而非物理连接,如果不及时关闭(而是等着GC来回收时才关闭),会在特定的繁忙情况下造成连接池满的异常。其实你对这个ExecuteCommand 代码讲解上的疏忽,并不影响你的帖子的主旨——基于抽象的System.Data.Common和System.Data层而并不依赖于System.Data.OleDb、System.Data.SqlClient等层面来设计程序,并且你演示了DbProviderFactory的作用。对于真正的架构师,往往就是在公司中被程序员经常将各种bug推脱为by design的bug,所以架构师不但要谨慎地讲解自己写出的代码(有错就赶紧纠正),而且在遇到(现在很常见的)娇生惯养脾气很大的程序员时要能够不去吵架而是仍然讲解清楚自己的主旨。
      

  46.   

    下班前 再回复93楼次因为你的那个问题,对于代码的书写来说,就更笨不是问题。
    只是你根本就没明白我为什么这么写。所以你才没能明白这个代码的思想。
    明白?
    重新回味下为什么这么写吧。
    打开连接后,当然要关闭连接。
    ADO。NET方面的的知识多了,你就明白了
      

  47.   

    呵呵,你的代码中最好改为类似这样的逻辑:    public static DataTable ExecuteCommand(DbCommand command) 
        { 
            DataTable table = null;         command.Connection.Open(); 
            try 
            { 
                DbDataReader read = command.ExecuteReader(); 
                table.Load(read); 
                read.Close(); 
                return table; 
            } 
            catch(Exception ex)
            {
                throw new Exception("在执行ExecuteCommand是发生了异常。",ex);  //将ex作为InnerException,然后继续抛出新的Exception。
            }
            finally 
            { 
                command.Connection.Close(); 
            }     } 当读取数据库发生异常时,要向ExecuteCommand调用者抛出异常通知,而不是返回空表(return table)给出错误的结果。如果隐藏异常,看似减少了异常,但是程序被错误的数据驱动之后会产生新的更大的异常,如果一路这样处理异常则必然会反映到程序运行结果上,用户会更加担心你的程序暗含着过多的疏忽,同时你自己要想快速查找到异常的真正发生地点也特别困难。
      

  48.   

    看看日期,好像快过年了。大家都大气点,其实看帖也很累呀,这长的贴子...。在技术方面,各有各的解决方案而已,谁的好,谁的巧,说出来,大家一起讨论讨论...做人嘛!何必...!C#咱们到底精通多少,你自己说了不算,我也说的不算...。
    我首先声明,我还是在校的学生。没有大家的见识广...
    To dsh198262:
       dsh198262兄只给了DBDAL层的部分代码,好像是通过.Net数据访问的基类着手来写的,只是写些基本的方法,这种设计模式我没有实践过,但是对我来说是给了我一个提醒。如果按dsh198262兄这种设计模式来说,在这里Static用的没有错,也是比较合理的(小生愚见)。
    但是我们最终逃脱不了选择一个数据库平台,就向dsh198262给的第一串代码这样,其实也很好。但是不一定也把类定义成Static吧。如果考虑到性能,我们似乎可以把Static去掉。
    根据楼主的心愿,是要在换数据库平台的时候能方便一点,根据楼主给的代码,我看不出到底在具体的平台怎么实现?毕竟数据库的提供者(Provider)不一样,数据层的代码也不一样呀!想问问到具体的平台(也就是以后的代码)该怎么办?