SPL快速入门

SmartPersistenceLayer 3 快速入门

前言

SmartPersistenceLayer SPL )自在博客园发布开始,就一直受到广大朋友的认可,那一套 SPL 的系列文档对 SPL 的使用与功能以及原理都作了充分的介绍,而这些系列文章有利于大家理解 SPL 的思想,将作为一个优秀的 .NET 系统框架持久层。

而那些文章由于比较分散,而且论述了一些架构思想,对一些初学者感觉有些困难,也应大家的要求,写一份简单的,实用的 SPL 应用手册,所以我接下来从实际场景模拟开发。

一、             引用

SPL 的发布形式是一个名为 PersistenceLayer.Dll DLL 文件 , 可以在我的 BLOG(http://www.cnblogs.com/tintown/ ) 上下载,因此只需要在项目中“添加引用”即可:

 

若要使用 ODP.NET 连接 Oracle 数据库,则用以上方式添加 Oracle.DataAccess.dll

若要使用 SPL 连接 MySql 数据库,则用以上方式添加 MySql.Data.dll

二、             配置文件与实体类

SPL 的配置文件与实体类可以使用我提供的 SmartRobot 进行生成,这可以大大加快开发效率,但工具毕竟是工具,不属于 SPL 持久层的必选部分。

连接数据库:

 

目前 SmartRobot 支持 Ms Sql Server Ms Access Oracle 数据库,如果是其他数据库只能只好手写实体类了或者等我升级喽 ;)

确定好要生成的实体类存放的地址,到时生成时会生成到相应的目录里。

 

配置每个表对应的实体类属性,默认实体类名称为“表名”加“ Entity ”字符,属性名默认与列名相同,上图中的“ 2 ”“ 3 ”操作对每个表都要重复一次的。

这时就会生成勾上的实体类到指定的目录下了。只要把指定的实体类引用到项目中即可,实体类默认使用的是 BusinessEntity 命名空间。因此在开发时,只要用到实体类的地方使用: using BusinessEntity 就可以了。

保存两个配置文件,放到你的项目中: ClassMap.xml DatabaseMap.xml

ClassMap.xml 为数据库表与实体类的映射关系

DatabaseMap.xml 为数据库连接配置:

Ms Sql Server 例如下:

< database name ="Northwind" type ="MsSqlServer">

         < parameter name ="Provider" value ="SQLOLEDB.1" />

         < parameter name ="Password" value ="tintown" />

         < parameter name ="Initial Catalog" value ="Northwind" />

         < parameter name ="User ID" value ="sa" />

         < parameter name ="Data Source" value ="(local)" />

         < classMapFile path ="ClassMap.xml" />

  </ database >

 

Ms Access 例如下:

< database name ="DMBCN" type ="MsAccess">

         < parameter name ="Provider" value ="Microsoft.Jet.OLEDB.4.0" />

         < parameter name ="Data Source" value ="dmbcn.mdb" />

         < classMapFile path ="ClassMap.xml" />

</ database >

Oracle 例如下:

< database name ="EDI" type ="Oracle">

         < parameter name ="Provider" value ="MSDAORA.1" />

         < parameter name ="Password" value ="tintown" />

         < parameter name ="User ID" value ="EDI" />

         < parameter name ="Data Source" value ="EDI.LIHINSOFT.COM" />

         < classMapFile path ="ClassMap.xml" />

  </ database >

 

ODP.NET 方式连接Oracle 例如下:

< database name ="Acci2004" type ="ODP">

         < parameter name ="Password" value ="tintown" />

         < parameter name ="User ID" value ="acci" />

         < parameter name ="Data Source" value ="oradb" />

         < parameter name ="Persist Security Info" value ="False" />

         < classMapFile path ="ClassMap.config" />

</ database >

 

MySql 数据库例如下:

< database name ="MySql" type ="MySql">

         < parameter name ="User Id" value ="root"/>

         < parameter name ="Data Source" value ="localhost"/>

         < parameter name ="Database" value ="mysql"/>

         < parameter name ="password" value ="tintown"/>

         < classMapFile path ="ClassMap.xml" />

</ database >

ClassMap.xml 的地址是相对于 DatabaseMap.xml 地址的,象例子中都是放在同一目录下,所以直接使用文件名即可 .

如果是连接多数据库,则可以配置多个 <database> 如:

<? xml version ="1.0" encoding ="utf-8"?>< map >

  < database name ="Northwind" type ="MsSqlServer">

    < parameter name ="Provider" value ="SQLOLEDB.1" />

    < parameter name ="Password" value ="tintown" />

    < parameter name ="Initial Catalog" value ="Northwind" />

    < parameter name ="User ID" value ="sa" />

    < parameter name ="Data Source" value ="(local)" />

    < classMapFile path ="ClassMap.xml" />

  </ database >

 

  < database name ="MySql" type ="MySql">

     < parameter name ="User Id" value ="root"/>

     < parameter name ="Data Source" value ="localhost"/>

     < parameter name ="Database" value ="mysql"/>

     < parameter name ="password" value ="tintown"/>

     < classMapFile path ="ClassMap2.xml" />

  </ database >

</ map >

所示为同时连接Ms Sql Server 数据库与MySql 数据库

三、             初始化数据连接

在页面的 Page_Onload 中使用如下进行初始化 ( 假设 DatabaseMap.xml 放在 Config 目录下 )

     string DatabaseXml="Config/DatabaseMap.xml";

PersistenceLayer.Setting.Instance().DatabaseMapFile=Server.MapPath(DatabaseXml);

以上的初始化只需要执行一次即会放在应用项目中,但 Web 会经常性的丢失 Application ,导致初始信息丢失,因此在每次执行数据库操作前都最好能进行初始化。

建议大家可以放在 BasePage , 采用 Appliction 进行控制:

if (Application["DatabaseSetting"]==null || Application["DatabaseSetting"].ToString()!="Y")

     {

         string DatabaseXml="Config/DatabaseMap.xml";

         PersistenceLayer.Setting.Instance().DatabaseMapFile=Server.MapPath(DatabaseXml);              Application["DatabaseSetting"]="Y";

}       

因为生成的实体类都是在BusinessEntity 命名空间下的,所以在要使用数据库访问的页面上加上:

Using PersistenceLayer;

Using BusinessEntity;

就可以直接使用SPL 的类与实体类了。

好了,非常简单,现在就可以开始体验 SPL 了。

四、             开发

假设我们目前有订单对象 SaleOrder( 字段名与属性名相同 )

字段名

类型

描述

Id

Varchar(50)

GUID 主键

No

Varchar(50)

订单编号

CustomId

Varchar(50)

客户 ID

CreateDate

DateTime

下单日期

 

 

 

 

订单明细对象 SaleOrderDetail( 字段名与属性名相同 )

Id

Varchar(50)

GUID 主键

OrderId

Varchar(50)

订单的 ID (外键)

ProductId

Varchar(50)

产品 ID( 外键 )

Quantity

Int

需求数量

Price

Decimal

单价

Amount

Decimal

小计

 

以下为模拟情况:

1)  在界面上选择了客户,并在 Grid 里选择了产品并输入了单价与数量,生成新订单:

Transaction t=new Transaction(); // 这肯定是要使用事务处理了

SaleOrderEntity Soe=new SaleOrderEntity();

Soe.Id=Guid.NewGuid().ToString(); // 生成新 GUID

Soe.No=this.txtNo.Text; // 取文本框里值

Soe.CustomId=this.ddlCustom.SelectedValue; // 取界面上客户下拉框里值

Soe.CreateDate=System.DateTime.Now;  // 取当前日期

t.AddSaveObject(Soe);     // 把订单主档加到事务中

 

for(int i=0;i<this.Grid.Rows.Count;i++)   // 编历整个 Gruid 生成一条条明细保存

{

        SaleOrderDetailEntity Sode=new SaleOrderDetailEntity();

        Sode.Id=Guid.NewGuid().ToString();// 生成新的 GUID

Sode.OrderId=Soe.Id;     // 取订单主档的 GUID

      Sode.ProductId=…// Grid 上取商品 ID

        Sode.Quantity=   // Grid 上取商品数量值

        Sode.Price=…    // Grid 上取商品单价值

        Sode.Amount=Sode.Quantity*Sode.Price;  // 汇总小计

        t.AddSaveObject(Sode);        // 把订单明细对象加到事务中

 

}

 

t.Process();   // 事务提交即可

 

2) 在查询界面要根据订单编号、订单时间段、客户进行综合查询

       RetrieveCriteria rc=New RetrieveCriteria(typeof(SaleOrderEntity)); // 创建一个针对订单主档的查询

       Condition c=rc.GetNewCondition();// 创建一个条件 ( 由于是综合查询,条件之间是 AND 关系 )

       If(this.txtNo.Text!=””)   // 如果在编号文本框中输入了查询条件

              c.AddEqualTo(SaleOrderEntity.__NO,this.txtNo.Text);// 添加 ”=” 条件 (SaleOrderEntity.__NO 是实体类中的常量,其值就是 ”No” ,为了减少去查对象属性的麻烦和输错的可能性,采用常量是最好的方式 )

       if(this.ddlCustom.SelectedValue!=””) // 如果选择了某一客户

              c.AddEqualTo(SaleOrderEntity.__CUSTOMID, this.ddlCustom.SelectedValue);

       if(this.txtDateFrom.Text!=””) // 如果开始日期不为空 , 则添加 ”>=” 比较

              c. AddGreaterThanOrEqualTo(SaleOrderEntity.__CREATEDATE,DateTime.Parse(this.txtDateFrom.Text);

       if(this.txtDateEnd.Text!=””)// 如果结束日期不为空,则添加 ”<” 比较

              c. AddLessThan(SaleOrderEntity.__CREATEDATE,DateTime.Parse(this.txtDateEnd.Text).AddDays(1);

       rc.OrderBy(SaleOrderEntity.__CREATEDATE,false);// 按创建时间的逆顺排

 

       DataTable dt=rc.AdDataTable(); // 返回 DataTable 以便绑定 Grid

3) 选中一条档后要显示主档信息与明细清单

SaleOrderEntity Soe=new SaleOrderEntity();

Soe.Id=Request[“Id”].ToString();    // 取得页面传过来的订单 ID

Soe.Retrieve(); // 通过主键值获取对象

If(Soe.IsPersistent) // 如果数据库里存在的话

{

        // 给界面上的控件赋值显示

       this.txtNo.Text=Soe.No;

        this.txtCreateDate.Text=Soe.CreateDate.ToString();

        ….

        // 绑定订单的所有明细信息

        RetrieveCriteria rc=new RetrieveCriteria(typeof(SaleOrderDetailEntity));

        Condition c=rc.GetNewCondition();

        c.AddEqualTo(SaleOrderDetailEntity.__ORDERID,Soe.Id);// 指定的订单 ID

        DataTable dt=rc.AsDataTable(); // 返回明细 DataTable

        this.Grid.DataSource=dt;

        this.Grid.DataBind();// 绑定

}

4) 进行订单主档与明细的修改 , 点击保存时:

       Transaction t=new Transaction(); // 这里肯定又要用到事务处理了

       SaleOrderEntity Soe.new SaleOrderEntity();

       Soe.Id=Request[“Id”].ToString(); // 取得订单 ID

       Soe.Retrieve();// 通过主键获取对象

       If(Soe.IsPersistent) // 如果对象存在的话进行修改操作

{

       Soe.No=this.txtNo.Text;

       Soe.CreateDate=DateTime.Parse(this.txtCreateDate.Text);

       ….

       t.AddSaveObject(Soe); // 自动判断 IsPersistent 就进行 Update 而不是 Insert

 

       // 选删除所有的明细记录,然后再重新把明细添进去,这样比较方便,避免了要判断是否进行修改,是否要进行删除与新增的麻烦

       DeleteCriteria dc=new DeleteCriteria(Typeof(SaleOrderDetailEntity));// 创建一个针对 SaleOrderDetail 的删除标准

       dc.GetNewCondition().AddEqualTo(SaleOrderDetailEntity.__ORDERID,Soe.Id);// 删除所有本订单 ID 的明细

       t.AddDeleteCriteria(dc);// 把这个删除标准加到事务中

 

       for(int i=0;i<this.Grid.Rows.Count;i++)  循环 Grid 重新添加到明细表中

       {

               SaleOrderDetailEntity Sode=new SaleOrderDetailEntity();

               Sode.Id=Guid.NewGuid().ToString();// 生成新的 GUID

Sode.OrderId=Soe.Id;     // 取订单主档的 GUID

             Sode.ProductId=…// Grid 上取商品 ID

               Sode.Quantity=   // Grid 上取商品数量值

               Sode.Price=…    // Grid 上取商品单价值

               Sode.Amount=Sode.Quantity*Sode.Price;  // 汇总小计

               t.AddSaveObject(Sode);        // 把订单明细对象加到事务中

 

}

}

5) 删除订单与订单明细

       Transaction t=new Transaction(); // 这里肯定又要用到事务处理了

       SaleOrderEntity Soe.new SaleOrderEntity();

       Soe.Id=Request[“Id”].ToString(); // 取得订单 ID

       Soe.Retrieve();// 通过主键获取对象

       If(Soe.IsPersistent) // 如果对象存在的话进行修改操作

{

       t.AddDeleteObject(Soe); // 把要删除的对象加到事务中

 

       // 选删除所有的明细记录

       DeleteCriteria dc=new DeleteCriteria(Typeof(SaleOrderDetailEntity));// 创建一个针对 SaleOrderDetail 的删除标准

       dc.GetNewCondition().AddEqualTo(SaleOrderDetailEntity.__ORDERID,Soe.Id);// 删除所有本订单 ID 的明细

       t.AddDeleteCriteria(dc);// 把这个删除标准加到事务中

 

       t.Process();// 提交删除

}

以上是我模拟的最常见的一些情况,以此让大家对 SPL 的使用有个初步的了解,至于 SPL 的更多的详细资料请访问我的 BLOG 专题: http://tintown.cnblogs.com/category/12787.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值