代码parameters

parameters add  时间:2021-02-19  阅读:()

第3章系统架构在进行具有一定规模的数据库应用系统开发时,如果仍采用传统的代码编写方式,将一个功能模块的所有代码都写在Form中的做法是非常不合适的.
因为以这种方式编写的代码,在面临需求变更时,所引发的修改往往是灾难性的.
即使是一个数据库IP地址的变更都可能会导致数十甚至上百处的代码变化(每个涉及连接数据库的代码都要修改连接字符串).
所有的代码堆砌在一个窗体内,职责繁杂造成代码可读性差,可维护性、可移植性差,违反了单一职责原则;在面临需求变更时,一定要通读所有代码,再在合适的位置做修改,违反了对修改关闭、对扩展开放的开放-关闭原则;所有代码没有任何抽象,不对接口编程,代码耦合度太高,无法适应较大的需求变更,违犯了依赖倒转原则.
例如,本书第8章的考试系统属于中小型应用系统,该系统分为两个子系统:教师端子系统和学生端子系统.
首先,两个子系统都访问同一个数据库,其中有许多访问数据库的操作及业务逻辑都是相同的,如果再像传统的编写方式一样将代码都放在各个Form中,那就无法实现代码的复用,必然造成大量的冗余,为后续扩展和维护带来麻烦.
此外,本考试系统面对的客户不同,其对于软件产品的经济投入也会不同,必然涉及不同的用户采用不同类型数据库的情况,如果代码不做到充分解耦,在面对数据库类型变更时,几乎都要把所有访问数据库的代码修改一遍,显然是不现实的.
采用一些典型架构开发软件,其目的就是为了使软件代码更具可维护、可扩展、可复用性,从而令系统更为灵活,可以适应任何合理的需求变更.
3.
1三层架构简介在软件体系架构设计中,分层式结构是最常见、也是最重要的一种结构,微软公司推荐的分层式结构一般分为三层,即三层架构(3-TierApplication),这三层从下至上分别为数据访问层、业务逻辑层以及表示层,如图3-1所示.
1.
数据访问层数据访问层(DataAccessLayer,DAL)又名持久层,该层负责访问数据库,通俗点讲就是该层负责实现对数据库各表的增、删、改、查操作,当然数据存储方式不一定是数据库,也可能是文本文件、XML文档等.
该层不负责任何业务逻辑的处理,更不涉及任何界面元素.
第3章系统架构732.
业务逻辑层业务逻辑层(BusinessLogicLayer,BLL)又称领域层.
该层是整个系统的核心,负责处理所有的业务流程,从简单的数据有图3-1三层架构示意图效性验证到复杂的对一整条业务链的处理.
例如商城购物,从查询商品到添加购物车,再到下订单,直至付款结束等过程.
当然,不排除个别软件项目业务逻辑简单,导致业务逻辑层代码较少的情况.
例如本章由于篇幅所限,所提供的示例业务逻辑简单,就会出现业务逻辑层"瘦小"的现象.
当业务逻辑层需要访问数据库时,它会通过调用数据访问层来实现,而不直接访问数据库.
这样可以使业务逻辑层的实现与具体数据库无关,从而有效解耦.
业务逻辑层同样不涉及任何界面元素.
3.
表示层表示层(UserInterface,UI)即用户界面,表示层可以是WinForm、WebForm甚至是控制台,该层负责用户与系统的交互,接收用户的输入及事件触发.
理想状态下,该层不应包含系统的业务逻辑,即使有逻辑代码,也应只与界面元素有关.
例如,根据用户的身份控制按钮的可用性等.
具体的业务逻辑可通过调用业务逻辑层来完成,该层不能直接调用数据访问层,更不能直接访问数据库.
如此分层具有以下优点:(1)分散关注:开发人员可以只关注自己所负责一层的技术实现.
例如,负责数据访问层的开发人员,可以不需要关心系统的任何业务逻辑,更不用关心界面的设计,只需要关心所访问的数据库类型及表结构,最大限度地实现对各数据表的增、删、改、查操作即可.
如此,对于开发人员的技术要求可以降到最低,项目经理也可以根据团队成员的专长,合理为其分配擅长的领域工作.
(2)松散耦合:三层之间呈线性调用,业务逻辑层的实现不依赖于数据访问层的具体实现,表示层的实现同样不依赖于业务逻辑层的具体实现,可以很容易用新的实现来替换原有层次的实现,而不会对其他层造成影响.
(3)逻辑复用:个别层代码所生成的组件(动态链接库文件DLL)可以直接被其他项目所使用.
例如,某系统最初只有WinForm版本,随着业务扩展,逐渐有了Web版、手机版等需求,但各版本功能一致,业务逻辑相同.
这样在新建Web版和手机版项目时,只需将原WinForm版项目中的业务逻辑层和数据访问层组件引用到新项目中,直接使用基于C#的管理信息系统开发(第2版)74即可,无须再重写代码.
当然,在获得优点的同时,分层也不可避免会付出一些"代价",其缺点是:(1)降低了系统性能:原本在不采用分层的情况下,UI可以直接访问数据库,但现在要通过层层调用才能达到同样的目的,必然会在运行效率上有所降低.

(2)容易导致级联修改:用户某些需求的变化,如用户觉得某个功能模块目前所维护的信息不够,需要再加入一些信息,势必导致UI的变化,为了存储这些数据也会导致相应数据表字段的增加,从而数据访问层和业务逻辑层都会受到影响,这就是级联修改.
3.
2简单三层架构简单三层架构即基本三层架构,其结构如图3-1所示.
现以一个小示例介绍简单三层架构的代码编写方式.
示例所用数据库及业务需求如下.
要求设计一个通讯录软件,实现对联系人类型的定制以及联系人的管理,即实现对联系人类型和联系人的增、删、改、查功能.
数据库名为MyDb,其中有两个数据表,名为LinkmanType(联系人类型)表和Linkmen(联系人)表,表结构分别如表3-1和表3-2所示.
表3-1LinkmanType(联系人类型)表结构字段名数据类型长度主键含义TypeIdnvarchar20是联系人类型编号typeNamenvarchar20否联系人类型名称表3-2Linkmen(联系人)表结构字段名数据类型长度主键含义lkmIdint4是联系人编号(自动加1)lkmNamenvarchar10否联系人姓名lkmMPNumnvarchar12否联系人移动电话lkmOPNumnvarchar20否联系人办公室电话lkmEmailnvarchar30否联系人电子邮箱lkmCompNamenvarchar50否联系人单位名称typeIdnvarchar20否联系人类型编号3.
2.
1数据访问层1.
创建一个空解决方案打开VisualStudio2012,单击"文件"→"新建"→"项目"菜单项,弹出图3-2所示的"新建项目"窗口,在该窗口左侧列表中单击"其他项目类型"→"VisualStudio解决方案",选择右侧的"空白解决方案",修改名称为"ThreeLayer",选择好保存位置,第3章系统架构75单击【确定】按钮,完成空解决方案的创建,如图3-3所示.
图3-2"新建项目"窗口图3-3创建后的空解决方案基于C#的管理信息系统开发(第2版)762.
创建数据访问层项目DAL在图3-3中右侧的"解决方案资源管理器"子窗口中的"解决方案ThreeLayer"节点上单击鼠标右键,选择"添加"→"新建项目",会再次弹出图3-2所示的"新建项目"窗口,在其中选择"VisualC#",在右侧选择"类库",将名称改为"DAL",单击【确定】按钮,此时,图3-3的解决方案会变成图3-4所示状态.
图3-4创建DAL项目之后的解决方案3.
编写数据访问层代码右击DAL项目中的Class1.
cs文件,在弹出菜单中选择"删除",将DAL默认创建的Class1.
cs文件删除.
再次右击DAL项目,在弹出菜单中选择"添加"→"类",弹出图3-5所示的"添加新项"窗口.
在图3-5中,将名称命名为"LinkmanType.
cs",单击【添加】按钮,在DAL项目中,会出现名为"LinkmanType.
cs"的类文件.
3.
1节提到数据访问层的任务就是实现对数据库的操作,即对各数据表数据的增加、删除、修改、查询.
作为LinkmanType类,其功能就是要实现对LinkmanType数据表的增加、删除、修改、查询操作.
DAL项目中的LinkmanType.
cs文件代码如下:namespaceDAL//需要手动引用System.
Data和System.
Data.
SqlClient命名空间{//LinkmanType类默认无访问修饰符,此处必须声明为public,因BLL在调用DAL中//该类时,属于跨项目访问,只有声明为public才能够被BLL所访问.
publicclassLinkmanType{第3章系统架构77图3-5"添加新项"窗口//////数据库连接字符串,server为数据库服务器的名字或IP地址,//database为数据库的名字,uid为数据库用户名,pwd为该用户的密码///publicstringconnString="server=(local);database=mydb;uid=test;pwd=test";//////插入数据的方法//////要插入的联系人类型编号///要插入的联系人类型名称///插入成功返回true,插入失败返回falsepublicboolinsert(stringtypeId,stringtypeName){try{SqlConnectionconn=newSqlConnection();conn.
ConnectionString=connString;conn.
Open();SqlCommandcmd=newSqlCommand();cmd.
Connection=conn;cmd.
CommandText="insertintolinkmantype(typeid,基于C#的管理信息系统开发(第2版)78typename)values(@typeid,@typename)";//参数形式的SQL语句//以下两句为SQL参数赋值cmd.
Parameters.
Add(newSqlParameter("@typeid",typeId));cmd.
Parameters.
Add(newSqlParameter("@typename",typeName));cmd.
ExecuteNonQuery();conn.
Close();returntrue;}catch{returnfalse;}}//////修改数据的方法//////要修改的联系人类型新编号///要修改的联系人类型新名称///要修改的联系人类型原编号///修改成功返回true,修改失败返回falsepublicboolupdate(stringtypeId,stringtypeName,stringoldTypeId){try{SqlConnectionconn=newSqlConnection();conn.
ConnectionString=connString;conn.
Open();SqlCommandcmd=newSqlCommand();cmd.
Connection=conn;cmd.
CommandText="updatelinkmantypesettypeid=@typeid,typename=@typenamewheretypeid=@oldTypeId";cmd.
Parameters.
Add(newSqlParameter("@typeid",typeId));cmd.
Parameters.
Add(newSqlParameter("@typename",typeName));cmd.
Parameters.
Add(newSqlParameter("@oldTypeId",oldTypeId));cmd.
ExecuteNonQuery();conn.
Close();returntrue;}catch{returnfalse;}}///第3章系统架构79///删除数据的方法//////要删除的联系人类型编号///删除成功返回true,删除失败返回falsepublicbooldelete(stringtypeId){try{SqlConnectionconn=newSqlConnection();conn.
ConnectionString=connString;conn.
Open();SqlCommandcmd=newSqlCommand();cmd.
Connection=conn;cmd.
CommandText="deletefromlinkmantypewheretypeid=@typeid";cmd.
Parameters.
Add(newSqlParameter("typeid",typeId));cmd.
ExecuteNonQuery();conn.
Close();returntrue;}catch{returnfalse;}}//////查询数据的方法//////strWhere为空字符串时,代表查询表中所有数据;///为非空时应传入查询依据,即where子句的内容,如"typeName='朋友'"等///返回null代表查询失败,返回非null代表查询成功,且///结果存在于返回的DataTable中publicDataTableselect(stringstrWhere){try{stringsql="select*fromlinkmantype";if(strWhere!
=""){sql+="where"+strWhere;}SqlConnectionconn=newSqlConnection();conn.
ConnectionString=connString;SqlDataAdapterda=newSqlDataAdapter(sql,conn);DataSetds=newDataSet();da.
Fill(ds);基于C#的管理信息系统开发(第2版)80returnds.
Tables[0];}catch{returnnull;}}}}接下来实现Linkmen表的数据访问层代码.
采用与创建LinkmanType.
cs类文件同样的方法,在DAL项目中创建Linkmen.
cs类文件.
在其中编写对Linkmen表的访问代码如下:namespaceDAL//需要手动引用System.
Data和System.
Data.
SqlClient命名空间{publicclassLinkmen{publicstringconnString="server=(local);database=mydb;uid=test;pwd=test";//////插入数据的方法//////姓名///移动电话///固定电话///电子邮箱///单位名称///联系人类型编号///插入成功返回true,插入失败返回falsepublicboolinsert(stringlkmName,stringlkmMPNum,stringlkmOPNum,stringlkmEmail,stringlkmCompName,stringtypeId){try{SqlConnectionconn=newSqlConnection();conn.
ConnectionString=connString;conn.
Open();SqlCommandcmd=newSqlCommand();cmd.
Connection=conn;cmd.
CommandText="insertintolinkmen(lkmname,lkmMPNum,lkmOPNum,lkmEmail,lkmCompName,typeId)values(@lkmname,@lkmMPNum,@lkmOPNum,@lkmEmail,@lkmCompName,@typeId)";cmd.
Parameters.
Add(newSqlParameter("@lkmname",lkmName));cmd.
Parameters.
Add(newSqlParameter("@lkmMPNum",lkmMPNum));cmd.
Parameters.
Add(newSqlParameter("@lkmOPNum",lkmOPNum));第3章系统架构81cmd.
Parameters.
Add(newSqlParameter("@lkmEmail",lkmEmail));cmd.
Parameters.
Add(newSqlParameter("@lkmCompName",lkmCompName));cmd.
Parameters.
Add(newSqlParameter("@typeId",typeId));cmd.
ExecuteNonQuery();conn.
Close();returntrue;}catch{returnfalse;}}//////修改数据的方法//////联系人编号///姓名///移动电话///固定电话///电子邮箱///单位名称///联系人类型编号///修改成功返回true,修改失败返回falsepublicboolupdate(stringlkmId,stringlkmName,stringlkmMPNum,stringlkmOPNum,stringlkmEmail,stringlkmCompName,stringtypeId){try{SqlConnectionconn=newSqlConnection();conn.
ConnectionString=connString;conn.
Open();SqlCommandcmd=newSqlCommand();cmd.
Connection=conn;cmd.
CommandText="updatelinkmensetlkmname=@lkmname,lkmMPNum=@lkmMPNum,lkmOPNum=@lkmOPNum,lkmEmail=@lkmEmail,lkmCompName=@lkmCompName,typeId=@typeIdwherelkmid=@lkmid";cmd.
Parameters.
Add(newSqlParameter("@lkmname",lkmName));cmd.
Parameters.
Add(newSqlParameter("@lkmMPNum",lkmMPNum));cmd.
Parameters.
Add(newSqlParameter("@lkmOPNum",lkmOPNum));cmd.
Parameters.
Add(newSqlParameter("@lkmEmail",lkmEmail));cmd.
Parameters.
Add(newSqlParameter("@lkmCompName",lkmCompName));基于C#的管理信息系统开发(第2版)82cmd.
Parameters.
Add(newSqlParameter("@typeId",typeId));cmd.
Parameters.
Add(newSqlParameter("@lkmid",lkmId));cmd.
ExecuteNonQuery();conn.
Close();returntrue;}catch{returnfalse;}}//////删除数据的方法//////要删除的联系人的编号///删除成功返回true,删除失败返回falsepublicbooldelete(stringlkmId){try{SqlConnectionconn=newSqlConnection();conn.
ConnectionString=connString;conn.
Open();SqlCommandcmd=newSqlCommand();cmd.
Connection=conn;cmd.
CommandText="deletefromlinkmenwherelkmid=@lkmid";cmd.
Parameters.
Add(newSqlParameter("@lkmid",lkmId));cmd.
ExecuteNonQuery();conn.
Close();returntrue;}catch{returnfalse;}}//////查询数据的方法//////strWhere为空字符串时,代表查询表中所有数据;///为非空时应传入查询依据,即where子句的内容,如"lkmName='张三'"等///返回null代表查询失败,返回非null代表查询成功,///且结果存在于返回的DataTable中publicDataTableselect(stringstrWhere){try第3章系统架构83{stringsql="selectlinkmen.
typeidastypeid,typename,lkmname,lkmid,lkmMPNum,lkmOPNum,lkmEmail,lkmCompNamefromlinkmenleftjoinlinkmantypeonlinkmen.
typeid=linkmantype.
typeid";if(strWhere!
=""){sql+="where"+strWhere;}SqlConnectionconn=newSqlConnection();conn.
ConnectionString=connString;SqlDataAdapterda=newSqlDataAdapter(sql,conn);DataSetds=newDataSet();da.
Fill(ds);returnds.
Tables[0];}catch{returnnull;}}}}上述代码为数据访问层的最基本实现,但还存在诸多不足:(1)增加、删除、修改功能的代码基本类似,存在大量的冗余.
事实上除了所执行的SQL语句以及所传递的SQL参数不同外,其他代码是一样的.
此外,各类的查询功能实现也极其相似,只是select语句不同罢了.
再者,每个类中都维护着同一个数据库连接字符串,不但冗余,更会给数据库迁移带来莫大的灾难,每次数据库迁移,都要修改每个类的连接字符串,何其麻烦!
因此,完全可以对这些冗余的代码进行精简.

(2)以各类的insert函数为例,操作联系人类型表的LinkmanType类中的insert函数有2个形参:typeId和typeName,分别代表要插入类型的两个字段,而操作联系人表的Linkmen类中的insert函数有则有6个参数:lkmName、lkmMPNum、lkmOPNum、lkmEmail、lkmCompName、typeId,可见,函数的形参个数与数据表的字段数是成正比的,如果一个数据表的字段数过多,势必导致相关函数的形参数过于冗长,非常不利于调用和规范化管理.
3.
2.
2数据访问通用类库解决以上第一个不足,精简冗余的数据库访问代码,可考虑再创建一个数据库访问辅助类库,将重复的代码进行封装.
1.
创建数据访问通用类库DBUtility右击解决方案,单击"添加"→"新建项目",创建一个名为"DBUtility"的类库项基于C#的管理信息系统开发(第2版)84目.
添加项目之后的解决方案列表如图3-6所示.
图3-6添加DBUtility类库后的解决方案2.
编写数据访问通用类库中的类代码在图3-6中,删除DBUtitlity项目中的Class1.
cs类文件,再新建一个名为"DbHelperSQL.
cs"的类文件,DbHelperSQL.
cs类代码如下:namespaceDBUtility//需要手动引用命名空间System.
Data和System.
Data.
SqlClient{publicclassDbHelperSQL{publicstaticstringconnString="server=(local);database=mydb;uid=test;pwd=test";//////数据增加、删除、修改要调用的通用方法//////要执行的SQL语句///所有要传给SQL语句的参数集合///返回true表示执行成功,false为执行失败publicstaticboolExecuteSql(stringsql,ListsqlParams){try{SqlConnectionconn=newSqlConnection();conn.
ConnectionString=connString;conn.
Open();SqlCommandcmd=newSqlCommand();cmd.
Connection=conn;cmd.
CommandText=sql;//遍历传过来的SQL参数集合,将其逐一加到SqlCommand对象的参数集合中for(inti=0;i///查询数据的通用方法//////select语句///返回null代表查询失败,返回非null代表查询成功,///且结果存在于返回的DataTable中publicstaticDataTableQuery(stringsql){try{SqlConnectionconn=newSqlConnection();conn.
ConnectionString=connString;SqlDataAdapterda=newSqlDataAdapter(sql,conn);DataSetds=newDataSet();da.
Fill(ds);//将sql语句的查询结果填充到ds中returnds.
Tables[0];}catch{returnnull;}}}}如此一来,数据访问层DAL项目中的各函数,只需要调用DBUtility中的函数即可实现对数据库的访问.
3.
为数据访问层项目DAL添加引用要在DAL中调用DBUtility中的类和函数,需将DBUtility项目引入到DAL项目中:右击DAL项目,在弹出式菜单中选择"添加引用",会弹出图3-7所示的"引用管理器"窗口.
在图3-7中,选择"解决方案"→"项目"选项,勾选"DBUtility"项目,单击【确定】按钮,会发现DAL项目的引用列表中,多出一个名为"DBUtility"的引用,如图3-8所示.
基于C#的管理信息系统开发(第2版)86图3-7"引用管理器"窗口图3-8添加引用后的DAL引用列表4.
修改3.
2.
1节中的数据访问层代码现在,可以在DAL项目中调用DBUtility中所有公开(public)的类和函数.
以Linkmen类的insert函数为例,此时,insert函数可通过调用DBUtility的DbHelperSQL类中的第3章系统架构87ExecuteSql函数来实现数据的插入,而无须书写重复冗余的代码,修改后的insert函数如下:publicboolinsert(stringlkmName,stringlkmMPNum,stringlkmOPNum,stringlkmEmail,stringlkmCompName,stringtypeId){stringsql="insertintolinkmen(lkmname,lkmMPNum,lkmOPNum,lkmEmail,lkmCompName,typeId)values(@lkmname,@lkmMPNum,@lkmOPNum,@lkmEmail,@lkmCompName,@typeId)";ListsqlParams=newList();//以下六句代码把要传给SQL语句的参数存入集合,以便传递给函数sqlParams.
Add(newSqlParameter("@lkmname",lkmName));sqlParams.
Add(newSqlParameter("@lkmMPNum",lkmMPNum));sqlParams.
Add(newSqlParameter("@lkmOPNum",lkmOPNum));sqlParams.
Add(newSqlParameter("@lkmEmail",lkmEmail));sqlParams.
Add(newSqlParameter("@lkmCompName",lkmCompName));sqlParams.
Add(newSqlParameter("@typeId",typeId));//调用通用类库中的ExecuteSql方法执行Sql语句returnDBUtility.
DbHelperSQL.
ExecuteSql(sql,sqlParams);}由上述代码可见,在insert函数中,已无须再编写SqlConnection、SqlCommand对象的创建和属性赋值、方法调用等代码.
同样,update、delete等函数也不必再写这些重复代码,代码复用度更高.
此外,由于连接字符串已写在了DbHelperSQL类中,不会在其他类中出现,对于数据库迁移所造成的修改量降到了最低——只需修改DbHelperSQL中的连接字符串即可.
完整的数据访问层代码将在解决第二个不足之后给出.

3.
2.
3实体类库针对第二个不足——函数参数个数因数据表字段过多而变得复杂的问题.
可以利用面向对象的思想,将数据表封装成类.
如对于LinkmanType表,可以定义Model.
LinkmanType类,其中包括2个成员变量typeId和typeName,分别对应LinkmanType表的2个字段.
而对于Linkmen表,可以定义Model.
Linkmen类,其中包含7个成员变量lkmId,lkmName,lkmMPNum,lkmOPNum,lkmEmail,lkmCompName,typeId,分别对应Linkmen表的7个字段.
这样在设计对应的insert和update函数时,可以用对应的类类型来作为形参,例如Linkmen类的insert函数,只需用以下方式定义即可:publicboolinsert(Model.
LinkmenmLKM);如此大大缩减了形参数量,简化了函数结构.
可以创建一个专门的类库,用于设计这些针对数据表结构而产生的类,我们称为实体(Model)类库.
基于C#的管理信息系统开发(第2版)881.
创建实体类库Model右击解决方案,单击"添加"→"新建项目",创建一个名为"Model"的类库项目.
添加项目之后的解决方案列表如图3-9所示.
图3-9添加Model之后的解决方案资源管理器2.
编写实体类库中的类代码在图3-9中,删除Model项目中的Class1.
cs类文件,再新建2个分别名为"LinkmanType.
cs"和"Linkmen.
cs"的类文件,各自代码如下:LinkmanType.
cs类代码如下:namespaceModel{publicclassLinkmanType{publicstringtypeId;publicstringtypeName;}}Linkmen.
cs类代码如下:namespaceModel{publicclassLinkmen{publicstringlkmId;publicstringlkmName;publicstringlkmMPNum;publicstringlkmOPNum;publicstringlkmEmail;publicstringlkmCompName;第3章系统架构89publicstringtypeId;}}3.
修改数据访问层代码首先,与引用DBUtility项目相同的方法,将Model项目引入到DAL项目中.
修改LinkmanType.
cs类文件如下:namespaceDAL//需要引入System.
Data和System.
Data.
SqlClient命名空间{publicclassLinkmanType{publicboolinsert(Model.
LinkmanTypemLKMT){stringsql="insertintolinkmantype(typeid,typename)values(@typeid,@typename)";ListsqlParams=newList();sqlParams.
Add(newSqlParameter("@typeid",mLKMT.
typeId));sqlParams.
Add(newSqlParameter("@typename",mLKMT.
typeName));returnDBUtility.
DbHelperSQL.
ExecuteSql(sql,sqlParams);}publicboolupdate(Model.
LinkmanTypemLKMT,stringoldTypeId){stringsql="updatelinkmantypesettypeid=@typeid,typename=@typenamewheretypeid=@oldTypeId";ListsqlParams=newList();sqlParams.
Add(newSqlParameter("@typeid",mLKMT.
typeId));sqlParams.
Add(newSqlParameter("@typename",mLKMT.
typeName));sqlParams.
Add(newSqlParameter("@oldTypeId",oldTypeId));returnDBUtility.
DbHelperSQL.
ExecuteSql(sql,sqlParams);}publicbooldelete(stringtypeId){stringsql="deletefromlinkmantypewheretypeid=@typeid";ListsqlParams=newList();sqlParams.
Add(newSqlParameter("typeid",typeId));returnDBUtility.
DbHelperSQL.
ExecuteSql(sql,sqlParams);}publicDataTableselect(stringstrWhere){stringsql="select*fromlinkmantype";if(strWhere!
=""){sql+="where"+strWhere;}returnDBUtility.
DbHelperSQL.
Query(sql);基于C#的管理信息系统开发(第2版)90}}}修改Linkmen类文件如下:namespaceDAL{publicclassLinkmen{publicboolinsert(Model.
LinkmenmLKM){stringsql="insertintolinkmen(lkmname,lkmMPNum,lkmOPNum,lkmEmail,lkmCompName,typeId)values(@lkmname,@lkmMPNum,@lkmOPNum,@lkmEmail,@lkmCompName,@typeId)";ListsqlParams=newList();sqlParams.
Add(newSqlParameter("@lkmname",mLKM.
lkmName));sqlParams.
Add(newSqlParameter("@lkmMPNum",mLKM.
lkmMPNum));sqlParams.
Add(newSqlParameter("@lkmOPNum",mLKM.
lkmOPNum));sqlParams.
Add(newSqlParameter("@lkmEmail",mLKM.
lkmEmail));sqlParams.
Add(newSqlParameter("@lkmCompName",mLKM.
lkmCompName));sqlParams.
Add(newSqlParameter("@typeId",mLKM.
typeId));returnDBUtility.
DbHelperSQL.
ExecuteSql(sql,sqlParams);}publicboolupdate(Model.
LinkmenmLKM){stringsql="updatelinkmensetlkmname=@lkmname,lkmMPNum=@lkmMPNum,lkmOPNum=@lkmOPNum,lkmEmail=@lkmEmail,lkmCompName=@lkmCompName,typeId=@typeIdwherelkmid=@lkmid";ListsqlParams=newList();sqlParams.
Add(newSqlParameter("@lkmname",mLKM.
lkmName));sqlParams.
Add(newSqlParameter("@lkmMPNum",mLKM.
lkmMPNum));sqlParams.
Add(newSqlParameter("@lkmOPNum",mLKM.
lkmOPNum));sqlParams.
Add(newSqlParameter("@lkmEmail",mLKM.
lkmEmail));sqlParams.
Add(newSqlParameter("@lkmCompName",mLKM.
lkmCompName));sqlParams.
Add(newSqlParameter("@typeId",mLKM.
typeId));sqlParams.
Add(newSqlParameter("@lkmid",mLKM.
lkmId));returnDBUtility.
DbHelperSQL.
ExecuteSql(sql,sqlParams);}第3章系统架构91publicbooldelete(stringlkmId){stringsql="deletefromlinkmenwherelkmid=@lkmid";ListsqlParams=newList();sqlParams.
Add(newSqlParameter("@lkmid",lkmId));returnDBUtility.
DbHelperSQL.
ExecuteSql(sql,sqlParams);}publicDataTableselect(stringstrWhere){stringsql="selectlinkmen.
typeidastypeid,typename,lkmname,lkmid,lkmMPNum,lkmOPNum,lkmEmail,lkmCompNamefromlinkmenleftjoinlinkmantypeonlinkmen.
typeid=linkmantype.
typeid";if(strWhere!
=""){sql+="where"+strWhere;}returnDBUtility.
DbHelperSQL.
Query(sql);}}}上述LinkmanType类和Linkmen类,明显较上一版本要精简得多,函数实现得到精简,函数参数也得到了精简.
此代码为本书简单三层架构终态的数据访问层代码结构.

CloudCone:$14/年KVM-512MB/10GB/3TB/洛杉矶机房

CloudCone发布了2021年的闪售活动,提供了几款年付VPS套餐,基于KVM架构,采用Intel® Xeon® Silver 4214 or Xeon® E5s CPU及SSD硬盘组RAID10,最低每年14.02美元起,支持PayPal或者支付宝付款。这是一家成立于2017年的国外VPS主机商,提供VPS和独立服务器租用,数据中心为美国洛杉矶MC机房。下面列出几款年付套餐配置信息。CPU:...

御云(RoyalYun):香港CN2 GIA VPS仅7.9元每月起,美国vps仅8.9/月,续费同价,可叠加优惠

御云怎么样?炎炎暑期即将来临,御云(royalyun)香港、美国服务器开启大特惠模式。御云是新成立的云服务提供商,主要提供香港、美国的云服务器,不久将开启虚拟主机业务。我们的香港和美国主机采用CN2 GIA线路。目前,香港cn2 gia vps仅7.9元每月起,美国vps仅8.9/月,续费同价,可叠加优惠,香港云服务器国内延迟一般在50ms左右,是搭建网站的最佳选择,但是请不要用于违法用途。点击进...

2021年国内/国外便宜VPS主机/云服务器商家推荐整理

2021年各大云服务商竞争尤为激烈,因为云服务商家的竞争我们可以选择更加便宜的VPS或云服务器,这样成本更低,选择空间更大。但是,如果我们是建站用途或者是稳定项目的,不要太过于追求便宜VPS或便宜云服务器,更需要追求稳定和服务。不同的商家有不同的特点,而且任何商家和线路不可能一直稳定,我们需要做的就是定期观察和数据定期备份。下面,请跟云服务器网(yuntue.com)小编来看一下2021年国内/国...

parameters add为你推荐
暴风影音怎么截图暴风影音3 如何截图不兼容手机软件与系统不兼容应该怎么办镜像文件是什么什么是文件镜像?什么是镜像文件?网易公开课怎么下载如何下载网易公开课idc前线怎么知道我电脑是3兆的宽带?ios系统ios是什么意思 ios系统是什么网管工具网吧管理软件都有哪些?rewritebasehttp怎么做自动跳转https怎么在图片上写文字如何用美图秀秀在照片上写字office2007简体中文版如何激活office2007 professional简体中文专业版啊?
域名升级访问中 域名注册使用godaddy 济南域名注册 私服服务器租用 浙江vps 西部数码vps 主机 12306抢票攻略 华为云主机 全能主机 免费ftp空间申请 免费防火墙 cdn加速原理 爱奇艺vip免费试用7天 域名dns 独享主机 linode支付宝 php服务器 美国迈阿密 可外链的相册 更多