




免费预览已结束,剩余15页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
ADO.NET 数据库实例教程ADO.NET数据库编程比较复杂,名目繁多的类、对象、属性、方法让每一个编程者都感觉恼火。本文旨在介绍ASP.NET Beta2数据库编程的主要内容,帮助编程者最快的了解ADO.NET数据库编程的精髓。一、 Managed Providers如果你是初学者,可能你会问,什么是Managed Providers?Managed Providers提供简单的方法连接和访问数据库,有点类似于数据库连接,当然又比它强的多。Managed Providers提供OleDb和SQL Server两种编程接口。因为SQL Server是微软自己的产品,因此,专门提供了一个针对SQL Server的接口,使用这个接口访问SQL Server的效率应该比使用OleDb强。NameSpaces本文所有的例子程序都需要使用以下NameSpaces:% Import Namespace=System.Data % Import Namespace=System.Data.Oledb %Connection为了连接数据库,必须使用OleDbConnection:Dim objConn as New OleDBConnection(Provider=Microsoft.Jet.OLEDB.4.0; Data Source=e:sffsitedbusers.mdb)当然,你也可以将具体的连接方法作为变量使用,在连接数据库以后,必须打开数据库:objConn.Open()这样,就可以使用数据库了,一般在最后,我们都要求关闭数据库连接:objConn.Close()objConn=NothingCommand连接数据库以后,就可以发送命令对数据库进行操作了,OleDbCommand允许发送命令对数据库进行操作。根据发送的SQL语句,我们可以对数据库进行几乎所有操作。Dim objCmd as New OleDbCommand(SELECT * From users, objConn)以上语句建立Command,根据习惯不同,也可以使用以下方法:Dim objCmd as New OleDbCommand()objCmd.Connection = objConnobjCmd.CommandText = SELECT * FROM users 还可以这样:Dim objCmd as New OleDbCommand(SQL String, connection string)仔细观察上面的语句,我们发现在定义OleDbCommand时,可以同时使用数据库连接OleDbConnection和数据库连接语句。以上代码并没有执行SQL语句,现在我们来看到底怎样执行:ExecuteNonQuery当执行没有返回数据的操作的时候,我们可以使用以上方法,比如插入数据、更新数据等操作,具体这样执行:objCmd.ExecuteNoQueryExecuteReader在需要一个Data Reader的时候,我们可以使用以上方法,具体这样执行:Dim objRd as OleDbDataReaderobjRd = objCmd.ExeuteReaderExecuteScalar使用ExecuteScalar方法来取得一个单个地返回数据,比如对数据的统计。Data ReaderOleDbReader是专门用来读取数据的对象,这个对象除了读数据以外,不能做其他任何数据库操作。尽管比较简单,但是在用来浏览数据的时候效率是非常高的。Dim objReader as OleDbDataReaderobjReader = objCmd.ExecuteReader While objReader.ReadResponse.Write(objReader.GetString(0) & br)End While以上语句读取Command的返回结果的第一个字段,这个字段是字符型数据。我们可以使用其他方法取得各种类型的数据: GetBoolean(x) GetByte(x) GetBytes(x) GetChar(x) GetChars(x) GetDataTypeName(x) 取得数据类型 GetDateTime(x) GetDecimal(x) GetDefaultStream(x) GetDouble(x) GetFieldType(x) GetFloat(x) GetGuid(x) GetInt16(x) GetInt32(x) GetInt64(x) GetName(x) 取得字段名 GetOrdinal(name) 根据字段名取得字段序号 GetString(x) GetTimeSpan(x) GetValue(x) GetValues(values() 以上方法都是Command返回数据。Data AdapterOleDbDataAdapter取得数据并且数据与DataSet之间建一座桥梁,可以这样使用:Dim objAdapter as New OleDbDataAdapter(SELECT * FROM users, objConn)实现方法有点类似于OleDbCommand。OleDbAdapter可以填充DataSet,也可以修改数据然后提交以实现对具体数据的修改:Dim ds as Dataset = New DataSet()objAdapter.Fill(ds, users)以上语句实现将SQL语句取得的Users表的数据填充到DataSet。MappingsMappings可以实现对DataSet的列取别名:objAdapter.TableMappings.Add(adbtable, users)With objAdapter.TableMappings(0).ColumnMappings.Add(PID, ID).Add(LastName, LName).Add(StreetAddress, Addy)End WithobjAdapter.Fill(ds)当使用了以上代码以后,就可以用ds.Tables(users)来代替ds.Tables(adbtable)了。Command Builder在下一章我们可以看到Command Builder的具体使用和强大功能。练习:如果你能理解以下代码,你就可以看下一章的内容了:% Import Namespace=System.Data % Import Namespace=System.Data.Oledb %script language=VB runat=serverSub Page_Load(sender as object, e as eventargs)Dim objConn as New OleDBConnection(Provider=Microsoft.Jet.OLEDB.4.0; Data Source=e:sffsitedbusers.mdb)objConn.Open()Dim ds as Dataset = New DataSet()Dim objAdapter as New OleDbDataAdapter(SELECT * FROM users, objConn)Dim objCmdBld As New OleDbCommandBuilder(objAdapter)objAdapter.Fill(ds, users)End Sub/script二、 Data Set本章将介绍DataSet对象,DataSet对象包含内容很多,我们基本上都将涉及,包括DataTables、DataRows等。什么是DataSet回头看看ASP,我们知道当查询数据的时候,返回的数据是放在RecordSet中的,RecordSet只能保存返回的一个表的数据,而且它很不灵活。DataSet在RecordSet上增加了很多功能,并且,它可以保存多个返回的数据表结果。DataSet被分解为很多部分比如DataTables和DataRows,可以使用它们创建一个DataSet而不一定要连接到一个具体的数据库。当然,DataSet本身就是离线数据,所有的数据都可以离线使用而不必一直连接到数据库,只有需要对数据库进行编辑的时候才需要连接到数据库。实践Dim ds1 As New DataSet()Dim dtable As new DataTable(people)With dtable.Columns.Add(FName, System.Type.GetType(System.String).Add(LName, System.Type.GetType(System.String).Add(UID, System.Type.GetType(System.Int32)End Withdtable.Columns(UID).AutoIncrement = True ds1.Tables.Add(dtable) dim pkey() as DataColumn = ds1.Tables(people).Columns(UID)ds1.Tables(people).PrimaryKey = pkey以上语句稍微有点复杂,我们来看看:前半部分我们建立了一个DataSet和一个叫People的DataTable,然后,我们为这个DataTable加入了三个列并将UID列设为自动递增。最后,将这个DataTable加入到了DataSet。第二部分我们现在不需要理解,只要知道定义了主键就可以了。DataTablesDataTable就是一个数据表,我们可以对这个表进行如:增加数据、修改数据等操作。我们也可以通过DataSet建立一个DataTable:Dim dtable As DataTable = ds1.Tables(people)这样,将DataSet的表People的结构和数据拷贝到了DataTable中,尽管它是无连接的,但是仍然可以通过修改这个DataSet来更新DataSet表,因此,如果我们在dtable中增加一列并且接受改变就以实现对DataSet的修改:Dim row as DataRow = dtable.NewRow()row(0) = Philiprow(1) = Quinndtable.Rows.Add(row)dtable.AcceptChanges这样我们就建立了一个新的DataRow,这和用dtable.NewRow()建立一个新的数据列一样,我们还可以给这个列取名了Fname。因为以上的DataTable来自DataSet,如果我们使用dtable.AcceptChanges方法更新DataTable,DataSet也会被更新:% Import Namespace=System.Data %script language=VB runat=serverSub Page_Load(sender as object, e as eventargs)Dim ds1 As New DataSet()Dim dtable As new DataTable(people)With dtable.Columns.Add(FName, System.Type.GetType(System.String).Add(LName, System.Type.GetType(System.String).Add(UID, System.Type.GetType(System.Int32)End Withdtable.Columns(UID).AutoIncrement = Trueds1.Tables.Add(dtable) Dim dtable2 As DataTable = ds1.Tables(people)Dim row as DataRow = dtable2.NewRow()row(0) = Philiprow(1) = Quinndtable2.Rows.Add(row)dtable2.AcceptChangesResponse.Write(ds1.Tables(people).Rows(0)(FName).ToString)End Sub/script以上代码将显示Philip,现在我们来看看具体过程:1、 建立一个DataSet和一个叫People的DataTable;2、 增加三个数据列并且设置它们的数据属性;3、 将它们加入到DataSet;4、 建立另外一个DataTable,这个DataTable是刚才建立的那个的拷贝;5、 用DataTable建立新的DataRow并加入数据;6、 接受数据改变同时更新了DataSet;7、 显示第一个数据列;DataRowsDataRow是DataTable的数据列,刚才我们已经看到,我们可以使用DataTable的以下方法建立一个新的DataRow:ds1.Tables(people).Rows(0)(FName) = Phil以上语句中,ds1.Tables(people)选择表people,.Rows(0)选择表的第一行,(FName)选择表的字段为Fname。DataRows是数据列的集合,通过以下语句取得:Dim drow as DataRowCollection = ds1.Tables(people).Rows对于DataRows,我们基本上不能做太多。如果针对一个具体的数据列,我们可以这样:Dim drow2 as DataRow = drow.Item(0)需要修改这个列的数据,可以这样:drow2(0) = Philipdrow2.AcceptChanges可能说了那么多,我们都觉得比较复杂,我们来看看这个图示:通过这个图示我们很容易就理清了DataSet、DataTable、DataRowCollection、DataRows、DataColumn和DataColumnCollection之间的相互关系。三、 DataSet的使用在第一章我们介绍了数据连接、执行查询等内容,第二章我们介绍了DataSet的方方面面,这一章我们将具体使用DataSet。DataSet - Data SourceDataSet和Data Source通过DataAdapter进行联系,当DataSet取得数据库数据以后,就和数据库断开连接,针对数据作的所有数据修改在没有提交以前都在DataSet里面保存。数据修改我们将通过一个小的举例来说明数据怎样被修改和提交。这是数据结构(Access设计)Field NameTypeFName LNameID FNameTextPhilipQuinn 1LName TextJoesphPayne2IDAutoNumberDouglasAdams 3MichaelOkuda4举例一:我们将一段一段的看程序代码:% Page Language=VB % Import Namespace=System.Data % Import Namespace=System.Data.Oledb %script language=VB runat=serverSub Page_Load(sender as object, e as eventargs)以上代码导入NameSpace同时说明编程语言为VB;Dim objConn as New OleDBConnection(Provider=Microsoft.Jet.OLEDB.4.0; Data Source=e:sffsitedbtest.mdb)objConn.Open()Dim ds as Dataset = New DataSet()Dim objAdapter as New OleDbDataAdapter(SELECT * FROM users, objConn)Dim objCmdBld as New OleDbCommandBuilder(objAdapter)objAdapter.Fill(ds, users)以上代码建立了Connection、DataAdapter和CommandBuilder,并且填充了DataSet。我们必须注意以下几点:一、 DataAdapter是数据和DataSet之间的桥梁;二、 CommandBuilder建SQL语句来执行;Dim drow as DataRow以上语句声明一个DataRow;drow = ds.Tables(users).NewRow()drow(0) = Genedrow(1) = Rodenberryds.Tables(users).Rows.Add(drow)drow = ds.Tables(users).NewRow()drow(0) = Maxwelldrow(1) = Stewartds.Tables(users).Rows.Add(drow)以上代码为DataSet增加一个新的列;objAdapter.Update(ds, users)以上代码将更新提交到数据库;End Sub/script现在看看数据库,会发现已经多了两列。另外一个举例我们可以看一个完整的举例:% Page Language=VB Debug=true % Import Namespace=System.Data % Import Namespace=System.Data.Oledb %script language=VB runat=serverSub Page_Load(sender as object, e as eventargs)Dim objConn as New OleDBConnection(Provider=Microsoft.Jet.OLEDB.4.0; Data Source=e:sffsitedbtest.mdb)objConn.Open()Dim ds as Dataset = New DataSet()Dim objAdapter as New OleDbDataAdapter(SELECT * FROM users, objConn)Dim objCmdBld as New OleDbCommandBuilder(objAdapter)objAdapter.Fill(ds, users)Dim drow as DataRowdrow = ds.Tables(users).Rows(1)drow(0) = Josephds.Tables(users).Rows(0).AcceptChangesobjAdapter.Update(ds, users)End Sub/script总结:以上我们知道了怎样更新DataSet的数据,可能那些并不是特别实用,下一章我们将涉及到用较好的方式显示数据和通过TextBox修改数据。四、数据显示和修改这一章我们将学习怎样显示数据,喜欢偷懒的你可以从拷贝以下代码开始:% Page Language=VB Debug=true % Import Namespace=System.Data % Import Namespace=System.Data.Oledb %script language=VB runat=serverSub Page_Load(sender as object, e as eventargs)Dim objConn as New OleDBConnection(Provider=Microsoft.Jet.OLEDB.4.0; Data Source=e:sffsitedbtest.mdb)objConn.Open()Dim ds as Dataset = New DataSet()Dim objAdapter as New OleDbDataAdapter(SELECT * FROM users, objConn)Dim objCmdBld as New OleDbCommandBuilder(objAdapter)objAdapter.Fill(ds, users)RepeaterRepeater是一个根据面板循环显示数据的控件。ItemTemplate:数据主要在这里显示AlternativeItemTemplate:利用它可以应用交替的样式;HeaderTemplate:头格式;SeparatorTemplate:分隔数据列;FooterTemplate:脚格式DataBind()DataBind()将数据与页面控件绑定:Repeater1.DataSource = ds.Tables(users).DefaultViewDataBind()以上代码将数据绑定到Repeater,如果没有绑定,数据不会显示。其他代码以下是举例的其他代码:Rpt.DataSource = ds.Tables(users).DefaultViewDataBind()End Sub/scripthtmlbodyfont face=Arial size=2asp:repeater id=Rpt runat=serverHeaderTemplatetable border=0 cellspacing=1 cellpadding=3trtd bgcolor=#6699FF width=25%Last Name/tdtd bgcolor=#6699FF width=25%First Name/td/tr/HeaderTemplateItemTemplatetr td%# Container.DataItem(LName) %/tdtd%# Container.DataItem(FName) %/td/tr/ItemTemplateFooterTemplate/table/FooterTemplate/asp:repeater/font/body/html说明:一、 设置了Repeater的DataSource;二、 绑定数据到Repeater;三、 Repeater数据控件开始;四、 HeadTemplate定义Repeater的头信息;五、 ItemTemplate定义具体数据填充;六、 FooterTemplate定义Repeater脚信息;DataListDataList和Repeater有点相似,和Repeater不同的是,DataList可以编辑数据。可以和Repeater一样使用Template,但是它具有两点不同: SelectedItemTemplate:显示选择的列; EditItemTemplate:显示要编辑的列;以下是一个使用DataList的简单举例:dl.DataSource = ds.Tables(users).DefaultViewDatabind()End SubSub dl_ItemCommand(sender as object, e as DataListCommandEventArgs)dl.SelectedIndex = e.Item.ItemIndexdl.DataBind()End Sub/scripthtmlbodyfont face=arial size=2form runat=serverasp:datalist id=dl runat=serverHeaderStyle-BackColor=#6699FFSelectedItemStyle-BackColor=#6666FFSelectedItemStyle-ForeColor=#FFFFFFRepeatLayout = tableRepeatDirection = verticalDataKeyField = IDOnItemCommand=dl_ItemCommandHeaderTemplateLast Name, click for full name./HeaderTemplateItemTemplateasp:linkbutton id=b1 runat=server Text=%# Container.DataItem(LName) % CommandName = select /br/ItemTemplateSelecteditemTemplate%# Container.DataItem(LName) & , & Container.DataItem(FName) %br/SelectedItemTemplate/asp:datalist/form/font/body/html说明:一、 绑定数据以后,建立了一个过程;二、 将DataList放入Form中,因为在以下的步骤中要求根据选择列刷新页面;三、 接着定义了一些数据显示格式;四、 HeaderTemplate:DataList头信息;五、 ItemTemplate:加入链接,定义事件;六、 SelectedItemTemplate:显示First 和 Last Name;DataGrid可能它是功能最强大的控件,不管简单还是复杂它都可以实现。和ItemTemplate不同,DataGrid有不同类型的列: Bound Columns:DataGird默认列显示方式; Button Columns:按钮列; Edit Command Column:可以编辑的列; Hyperlink Column :带连接的列; Templated Column :自定义列显示;dg.DataSource = ds.tables(users).DefaultViewDataBind()End Sub/scriptasp:DataGrid id=dg runat=server /以上代码很简单,就是绑定数据。dg.DataSource = ds.tables(users).DefaultViewDataBind()End Sub/scriptasp:DataGrid id=dg runat=serverBorderColor=blackGridLines=verticalcellpadding=3cellspacing=1width=50%Font-Names=ArialFont-Size=10ptHeaderStyle-BackColor=#6699FFAlternatingItemStyle-BackColor=#6666FFAutoGenerateColumns=FalseColumnsasp:BoundColumn HeaderText=ID DataField=ID /asp:templateColumn HeaderText=NameItemTemplateasp:label id=Name runat=server Text=%# Container.DataItem(FName) & & Container.DataItem(LName) % /ItemTemplate/asp:templatecolumn/Columns/asp:datagrid可能有一点复杂,我们看说明:一、 绑定数据以后,设置了一些DataSet显示效果,包括字体、表宽、头信息背景颜色、交替背景颜色、是否自动生成数据表等;二、 加入一个自定义格式列,该列名为Name,由字段Fname和Lname组成;现在才刚刚开始可能现在你还没有感受到DataSet的好处,以后的章节我们将学习怎样编辑数据。五、理解DataGrid数据放入DataGrid以后,除了一般的显示以外,我们还需要对这些数据进行编辑、修改。看了前几个章节你可能认为DataGrid比较简单,数据处理也比较方便。其实,如果需要真正做一个应用,我们会发现前面的知识还远远不够。以下所用的数据库和前面的章节完全相同,一些设置我们可以参考前面章节。我们先来看代码:% Page Language=VB Debug=true % Import Namespace=System.Data % Import Namespace=System.Data.Oledb %script language=VB runat=serverDim objConn as New OleDBConnection(Provider=Microsoft.Jet.OLEDB.4.0; Data Source=e:sffsitedbtest.mdb)Dim ds as Dataset = New DataSet()Dim objAdapter as New OleDbDataAdapter(SELECT * FROM users, objConn)Sub Page_Load(sender as object, e as eventargs)objConn.Open()objAdapter.Fill(ds, users)dg.DataSource = dsdg.DataMember = usersIf Not Page.IsPostBack Thendg.Databind()End IfEnd Subsub dg_edit(sender as object, e as DataGridCommandEventArgs)dg.edititemindex = -1dg.DataBind()end subsub dg_cancel(sender as object, e as DataGridCommandEventArgs)dg.edititemindex = -1dg.databind()end sub/script以上程序代码很简单直接,我们应该都可以看懂。只是需要注意Page_Load的对数据绑定的处理,在几乎所有的数据库程序中,我们都使用这种方式处理数据绑定,所以,这个处理方式一定要牢记。以上是数据连接和事件处理部分,现在我们看DataGrid部分。自定义DataGrid以下代码演示了自定义DataGrid的实现,在实际应用中,我们基本都是这样使用DataGrid,以下代码很有典型性,可以作为一个好的参考。form runat=serverasp:DataGrid id=dg runat=serverBordercolor=blackgridlines=verticalfont-names=Arialfont-size=10ptHeaderStyle-BackColor=#FFCC00 表格头信息ItemStyle-BackColor=#FFCC66 每行背景色 AlternatingItemStyle-BackColor=#FFFFFF 交替背景色AutoGenerateColumns=False 自定义每行OnEditCommand=dg_edit 以下三个事件处理OnCancelCommand=dg_cancelOnUpdateCommand=dg_update自定义每行显示Columnsasp:boundcolumn readonly=true headertext=ID DataField=Auto /asp:boundcolumn headertext=First Name DataField=Number1 /asp:boundcolumn headertext=Last Name Datafield=Number2 /asp:editcommandcolumn edittext=Edit CancelText=Cancel UpdateText=Save HeaderText= /Columns/asp:dataGrid/form以上代码中,自定义了数据编辑列,这些相应的处理在前面已经给出代码。我们现在来看事件处理。OnEditCommand以下是编辑按钮处理代码:sub dg_edit(sender as object, e as DataGridCommandEventArgs)dg.edititemindex = e.item.itemindexdg.databind()end sub以上代码需要注意的是,e.item.itemindex就是我们需要编辑的那行数据。在对数据作任何变动以后,都需要重新绑定数据,也就是DataBing()。OnCancelCommand取消按钮处理和上面的编辑按钮处理差不多,区别的是,在这里,dg.edititemindex被设为-1,也就是将数据恢复到原来状态。OnUpdateCommand先来看数据更新代码:sub dg_update(sender as object, e as DataGridCommandEventArgs)Dim FNAME As TextBox = e.item.cells(1).controls(0)Dim LNAME As TextBox = e.item.cells(2).controls(0)Dim sqlstr As Stringsqlstr = UPDATE users SET & _Number1 = & FNAME.Text & , & _Number2 = & LNAME.Text & & _WHERE Auto = & e.item.cells(0).textDim objCommand = New OLEDBCommand(sqlstr, objConn)objCommand.ExecuteNonQuery()ds.Tables.ClearobjAdapter.Fill(ds, users)dg.edititemindex = -1dg.DataBind()end sub以上代码将建立两个TextBox,这两个TextBox就是DataGrid中的复本。然后用SQL语句更新数据,最后重新绑定数据。总结以上代码可能初学者比较难懂,而且,上面的数据更新方法也不是很好。但是为了我们更好理解,我们还是可以参考以上代码。六、DataGrid数据排序数据排序在一些特殊的场合是必要的。下面我们将详细介绍DataGrid中的数据排序功能。在对DataGrid数据实现排序功能以前,我们需要做以下准备:1、 将AutoGenerateColumns设为打开,这样自定义数据列功能将失去,同时也将失去直接编辑功能。其实这无关紧要的,数据显示和编辑分开不同页面这种模式其实是现在比较认可的方法。2、 必须将AllowSorting设为真,这样,在每一列数据的标题将建立一个链接,点击这个链接将按照这个字段排序。3、 必须建立排序事件,也就是OnSortCommand。现在看代码:asp:DataGrid id=dg runat=serverBordercolor=blackgridlines=verticalfont-names=Arialfont-size=10ptHeaderStyle-BackColor=#FFCC00ItemStyle-BackColor=#FFCC66AlternatingItemStyle-BackColor=#FFFFFFAut
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- vte考试试题及答案
- spss上机考试及答案
- 国耻知识竞赛试题及答案
- DB61T 499-2010 地理标志产品 略阳杜仲
- 齐鲁名校教科研协作体 山东、湖北部分重点中学2025-2026学年数学高三上期末统考模拟试题
- 江西省宜春市丰城九中2025-2026学年数学高三第一学期期末学业水平测试试题
- 上海南洋模范2025年数学高三上期末复习检测试题
- 幼儿教师资格证考试试题及答案
- 2025口腔组织病理学考试题库及参考答案
- 2025上海研名医疗科技有限公司招聘1人考试参考试题及答案解析
- 大模型时代:生成式AI发展与科技创新范式
- 江苏欧立可化工新材料有限公司年产10万吨石油添加剂N-甲基苯胺项目环评资料环境影响
- 黄浦区2024-2025学年六年级下学期期末考试数学试卷及答案(上海新教材沪教版)
- 2025-2030中国香皂市场销售动态及竞争策略分析报告
- 2025安全注射培训
- 劳动仲裁内部培训
- 中国方言课件图文教学
- 中国市政工程专业市场深度调查评估及投资方向研究报告
- 女职工普法宣传教学课件
- 手术后切口愈合不良查房
- 合资研发中心管理制度
评论
0/150
提交评论