• ASP.NET3.5 企业级项目开发 -- 第二章(续) 数据访问层(DAL)的开发解决方案提出


                      ASP.NET3.5 企业级项目开发 -- 第二章(续) 数据访问层(DAL)的开发解决方案提出

           前言:首先给大家说声"对不起",因为自从打算写这系列的文章以来,得到大家很多的支持,谢谢大家!最近因为公司的事和朋友找工作的事,没有怎么接着写了,也调了大家的胃口,还希望园子里的朋友原谅!

           本篇主要是讲述数据层的开发,之前的一篇文章已经给出了很多的选中的方案,如SqlHelper,DataTable/DataSet,以及自定义实体。但是我们说过了,那些方案都有不尽人意的地方,所以我们就提出用Linq,找个方案就比之前好一些,但是也不是那么完美了。
     
           本篇的话题如下:
           Linq中自定义方法
           提出解决方案

           Linq中自定义方法

           在此之前,我们先要讲清楚一个问题:在Linq中的自定义存储过程。
           我们知道,当我们把数据库中的一张表拖放到Linq的ORM设计器上以后,ORM就自动生成了很多的方法,如Delete,Update,Insert方法,这些方法都是自动生成的,一般是没有什么问题的,但是一个项目的开发中,很多时候我们都要把这些方法进行定制。那么我们就要用自己的存储过程。

           一般情况下,我们可以在我们的数据库中定义一些的存储过程,如下,我们在之前定义的ENTUserAccount表中添加一条数据:
     

    Code

     
           我们接来进行下面的操作;
           1.把这个存储过程拖放到ORM设计器的右边的方法面板中,这样存储过程就自动的生成一个方法。
           2.在ORM中点击ENTUserAccount表,选择属性中的Insert,如图:(插图出现问题,大家原谅!!!)
     
           3.在出现的面板中,我们选择Customer(自定义)。选择我们之前由存储过程实生成的的方法,确认就OK了。

           如果我们在我们的以后的代码中调用HRPaidTimeOffDataContext.InsertENTUseAccount方法,那么此时我们就实际上调用我们自定义的方法了,之前自动生成的Insert方法就不调用了。
     
           同理,Update,Delete方法的自定义也是一样的。
     
           提出解决方案

           约定:我们以后的存储过程的命名采用方式:表名+操作,如ENTUserAccountInsert。

           首先我们创建一下存储过程:

           ENTUserAccount表中插入数据


     

    Code

           ENTUserAccount表中更新数据

    Code

            获取ENTUserAccount表中所有记录


    Code

           通过ENTUserAccountId来查找记录
     
     

    Code

            以前的存储过程没有和大家以前做的项目一样,是很普通的一些存储过程。
           写完上面的存储过程之后,大家把Insert,Update,Delete的存储过程拖到ORM的方法面板中生成方法,然后按照我们之前说的方法定制,把ENTUserAccount的Update,Insert等方法都配置成为我们自己写的方法。


           注意:对于Select的存储过程,我们不应该把它们直接拖到方法面板中,我们而是把ENTUserAccountSelectAll,ENTUserAccountSelectById存储过程拖到到ORM设计器中的ENTUserAccount表上。因为只有这样,自定生成的代码才返回ENTUserAccount类的类型;如果是像之前那样拖到方法面板中,那么返回值就是ISingle<ENTUserAccount>,大家之后会看到原因的。
     
           之前,我们就在V2.PaidTimeOffDAL中创建一个文件夹,命名为Framework。让后在这个文件夹下面添加一个类,命名为IENTBaseEntity.cs

    Code

           因为Binary 类型是在System.Data.Linq下的,所以我们在类中添加这个命名空间的引用。
     
           大家在想:为什么我们要定义这么一个接口?
     
           原因有两点:
           1.因为我们的这个项目中之后会有审计跟踪的功能,就是说数据库中记录的每次修改都会记录下是谁在什么时候修改的,而且我们的所有的表中都会有上面的5个字段。定义接口这样做为了使得每个类都必需定义必需有上面的5个字段。


           2.定义接口,可以实现一些依赖倒置的原则,以后大家会看到效果的。

     
           添加完上面的类之后,那么我们就再添加一个类:CustomizedEntities.cs ,这个类不在Framework文件夹中,而是直接加在外面的。

     using V2.PaidTimeOffDAL.Framework;
     
    namespace V2.PaidTimeOffDAL
     {
      
    public partial class ENTUserAccount : IENTBaseEntity { }
     }

           大家可能会想:ENTUserAccount类是个partial类,那么就说明这个类之前已经在什么地方有了的?
           不错!我们之前说要把ENTUserAccountById的存储过程拖到ENTUserAccount表上,其实我们就是想生成这个和数据表同名的ENTUserAccount类。
     我们使得这个类实现这个接口,那么我们以后就可以"针对接口编程"。


           其实我们知道我们的DAL数据层的功能很明了:和数据库直接打交道,实现增,删,改,查操作。
     
           为了使得我们所有的数据操作统一,我们定义了一个基类,以后的所有数据库操作类都实现它。
           我们在Framework文件夹中添加类:ENTBaseData.cs
     
     

    Code


     

          类的编写也不难理解:就是有写操作数据的方法。大家还要注意一点:Delete方法的实现,我们采用了Template Method设计模式,也就是常说的"钩子方法",实现的原因,现在讲述不是很好理解,没有一种自然的过程,我以后会说的。
     
           这样我们就定义这样的一个基类,然后针对每个表都有数据操作,那么我们就让每个表的数据操作类都继承这个基类。
           注意:大家在上面的基类中,没有看到Insert和Update方法,只是有原因的。如果我们在基类中写了Insert方法,就会传入一个T参数,如下:
         

      public bool Insert(T entUserAccount)

     
           这样是没有错,但是不是很好。如果我们的entUseAccount中如果有写字段没有赋值,那么我们插入就出问题。
           所以我们的实现方法是:直接在不同的数据操作类中,针对特定的表写Insert和Update方法。
     
           我们就来看看ENTUserAccount数据表的操作类的实现:


     

    Code

      

           上面方法很简单:直接调用自动生成的方法。
     
           至于DBHelper.GetHRPaidTimeOffConnectionString()方法,就是把数据库的链接字符串从web.config文件中读出。
     
           下面我们就来看看Delete方法的实现:

      public override void Delete(HRPaidTimeOffDataContext db, int id)
            {
                db.ENTUserAccountDelete(id);
            }

           我们之前说过,只是一个Template Method模式的使用,使用的意图是:把具体实现延迟到子类。可能在以后的项目中,我们的数据库要更改了,表也改了,那时,我们的 ENTUserAccount数据表可能改为User表,那么我们之前实现的代码不变,只要重写Delete方法就行了,如
     

     public override void Delete(HRPaidTimeOffDataContext db, int id)
            {
                db. User Delete(id);
            }
     

     
           下面,我们就来看看Insert方法:

           其实实现也很简单,我们采用和SqlHelper相同的方式:第一个方法传入HRPaidTimeOffDataContext ,第二个方法传入connectionString
     
           而且我们传入的参数是和ENTUserAccount表相对应的字段,这样就比只是传入一个ENTUserAccount类要好。

    Code


            同理,Update方法实现如下;
     

    Code

     
           

          到这里,我们的DAL的实现的示例就到这里,当然,我们这里只有一个表,但是我们通过这个示例知道了我们之后实现方法,其他表的实现数据操作的方式一样的,随着深入的讲述,大家会看到的!

       为了大家交流,已经创建企业项目开发团队,希望大家也以后会把有关企业开发的文章放入团队中,希望大家积极参加这个团队。而且我以后也会发表更多的项目示例,大家一起学习进步!

           注:大家留言后,我手动的添加。因为dudu说只能这样添加,现在博客园团队的功能很有限,只能手动添加成员!

  • 相关阅读:
    一个有趣的js现象
    根相对路径的简单例子
    几道简单有趣的js题(一)
    js流程控制题——如何实现一个LazyMan
    HTML5 十大新特性(十)——Web Socket
    HTML5 十大新特性(九)——Web Storage
    HTML5 十大新特性(八)——Web Worker
    HTML5 十大新特性(七)——拖放API
    HTML5 十大新特性(六)——地理定位
    HTML5 十大新特性(五)——SVG绘图
  • 原文地址:https://www.cnblogs.com/yanyangtian/p/1509000.html
Copyright © 2020-2023  润新知