创建强类型DataSet --转自:小菜之智能客户端(2)

这一篇主要讲述创建强类型DataSet,在TaskVision与IssueVision中都使用强类型DataSet。
强类型DataSet相比较非类型DataSet优点:方便,提供的支持多,可靠。
强类型DataSet相比较非类型DataSet缺点:有优点当然也就有缺点,对于强类型DataSet,如果数据库结构改变,我们需要重新生成xsd架构进而重新生成强类型DataSet。可见数据库结构与xsd架构的稳定对于强类型而言非常重要。

下面小菜会举例说明让你很清晰的感受到区别,所以这篇文章会比较长,大家先做好心理准备,不过保证是你在网上看不到的文章。

(一)、TaskVision数据库
TaskVision数据库名称:TaskVision,含有表Projects。

1、表Projects (存放项目的有关信息)

列名数据类型长度允许空描述
ProjectIDint4 项目表的主键,自动编号
ProjectNamevarchar20 项目名称
ProjectDescriptionvarchar100 项目描述
IsDeletedbit1 记录是否删除标记,默认值(0)
DateCreateddatetime8 项目创建日期,默认值(getdate())

表中已有内容:
image
对应本地应用程序界面:
image 
TaskVision使用的是强类型DataSet:表Projects对应DataSetProjects.xsd。

强类型DataSet在vs2002/vs2003与vs2005的差别比较大。
所以小菜先使用vs2003,然后再使用vs2005,这样大家的感触会比较深些。

(二)、使用vs2003创建XML架构,生成强类型DataSet
使用vs2003创建一个Asp.Net Web服务,添加新项:选择XML架构。(注意:不是数据集,下面会说到。)
XML架构就是XML Schema,文件扩展名为xsd。这些在第一篇讲过了。
不清楚可以返回第一篇:小菜之智能客户端(1)XML,DTD,XSD
image 
名称为:DataSetProjects.xsd
在服务器资源管理器中添加到TaskVision数据库的连接,打开DataSetProjects.xsd然后把Projects表拉入。
如下图:
image 
对应XML Schema代码如下:

<? xml version="1.0" encoding="utf-8"  ?>
< xs:schema  id ="DataSetProjects"  
    targetNamespace
="http://tempuri.org/DataSetProjects.xsd"  
    elementFormDefault
="qualified"
    xmlns
="http://tempuri.org/DataSetProjects.xsd"  
    xmlns:mstns
="http://tempuri.org/DataSetProjects.xsd"
    xmlns:xs
="http://www.w3.org/2001/XMLSchema"  
    xmlns:msdata
="urn:schemas-microsoft-com:xml-msdata" >
    
< xs:element  name ="Document"  msdata:Locale ="zh-CN" >
        
< xs:complexType >
            
< xs:choice  maxOccurs ="unbounded" >
                
< xs:element  name ="Projects" >
                    
< xs:complexType >
                        
< xs:sequence >
                            
< xs:element  name ="ProjectID"  msdata:ReadOnly ="true"  
                                msdata:AutoIncrement
="true"  type ="xs:int"   />
                            
< xs:element  name ="ProjectName"  type ="xs:string"   />
                            
< xs:element  name ="ProjectDescription"  type ="xs:string"   />
                            
< xs:element  name ="IsDeleted"  type ="xs:boolean"   />
                            
< xs:element  name ="DateCreated"  type ="xs:dateTime"   />
                        
</ xs:sequence >
                    
</ xs:complexType >
                
</ xs:element >
            
</ xs:choice >
        
</ xs:complexType >
        
< xs:unique  name ="DocumentKey1"  msdata:PrimaryKey ="true" >
            
< xs:selector  xpath =".//mstns:Projects"   />
            
< xs:field  xpath ="mstns:ProjectID"   />
        
</ xs:unique >
    
</ xs:element >
</ xs:schema >

补充:xs:unique为唯一性的约束,只要求数据必须是唯一的,但可以允许为空。
xs:key为键约束,要求比较严格,必须是唯一的,而且不允许空。
         不过在unique中指明了该约束为主键约束:msdata:PrimaryKey="true"也就是在架构中声明ProjectID为主键
         xs:selector的xpath属性,定位键所要应用到的数据表。
         xs:field的xpath属性,表示定位键所要应用的字段。         
         xs:element name="ProjectID" msdata:ReadOnly="true'为只读。msdata:AutoIncrement = "true"指明了为自增。指明自增默认种子为0,步长为1。即和数据库中的ProjectID一致。

其它XML Schema相关代码在第一篇中基本都说过了,不是很清楚的话可以返回第一篇:
1、我们不想显示IsDeleted字段,把它删掉。
(可以在视图中删除,也可以在代码中删除:<xs:element name="IsDeleted" type="xs:boolean" />
2、Document名称不直观,把它改成DataSetProjects。
(可以在视图中修改,也可以在代码中修改:<xs:element name="Document" msdata:Locale="zh-CN">改成<xs:element name="DataSetProjects" msdata:Locale="zh-CN">
3、将DataSetProjects属性IsDataSet设为true。
(可以在属性窗口中修改如下图:)
image
(也可以在代码中修改:<xs:element name="DataSetProjects" msdata:Locale="zh-CN">修改为<xs:element name="DataSetProjects" msdata:Locale="zh-CN" msdata:IsDataSet="true">

经过修改后视图如下图:
image
查看其XML源码如下:

<? xml version="1.0" encoding="utf-8"  ?>
< xs:schema  id ="DataSetProjects"  
    targetNamespace
="http://tempuri.org/DataSetProjects.xsd"  
    elementFormDefault
="qualified"
    xmlns
="http://tempuri.org/DataSetProjects.xsd"  
    xmlns:mstns
="http://tempuri.org/DataSetProjects.xsd"
    xmlns:xs
="http://www.w3.org/2001/XMLSchema"  
    xmlns:msdata
="urn:schemas-microsoft-com:xml-msdata" >
    
< xs:element  name ="DataSetProjects"  msdata:Locale ="zh-CN"  msdata:IsDataSet ="true" >
        
< xs:complexType >
            
< xs:choice  maxOccurs ="unbounded" >
                
< xs:element  name ="Projects" >
                    
< xs:complexType >
                        
< xs:sequence >
                            
< xs:element  name ="ProjectID"  msdata:ReadOnly ="true"  
                                msdata:AutoIncrement
="true"  type ="xs:int"   />
                            
< xs:element  name ="ProjectName"  type ="xs:string"   />
                            
< xs:element  name ="ProjectDescription"  type ="xs:string"   />
                            
< xs:element  name ="DateCreated"  type ="xs:dateTime"   />
                        
</ xs:sequence >
                    
</ xs:complexType >
                
</ xs:element >
            
</ xs:choice >
        
</ xs:complexType >
        
< xs:unique  name ="DocumentKey1"  msdata:PrimaryKey ="true" >
            
< xs:selector  xpath =".//mstns:Projects"   />
            
< xs:field  xpath ="mstns:ProjectID"   />
        
</ xs:unique >
    
</ xs:element >
</ xs:schema >

在TaskVision的Web服务项目中的:DataService.asmx中我们可以看到如下Web方法。

[WebMethod(Description = " Returns a project DataSet containing exactly one table named 'Projects'. " )]
public  DataSetProjects GetProjects()
{
    DataSetProjects ds 
= new DataSetProjects();
    daProjects.Fill(ds, 
"Projects");

    
return ds;
}

小菜将关于客户端用户验证的代码去掉,之后会专门来说客户端用户验证这一块。

关键看DataSetProjects ds = new DataSetProjects();这一行代码。
DataSetProjects 是什么呢?它是强类型DataSet。上面的代码就像DataSet ds = new DataSet();不过DataSet是非类型。

在我们的程序中没有DataSetProjects这个类啊?我们如何使用上面的代码啊?
我们可以利用之前创建的DataSetProjects.xsd这个XML架构来生成强类型的DataSet:DataSetProjects
怎么创建呢?很简单动下你的鼠标就行了。
打开DataSetProjects.xsd,鼠标右键,单击生成数据集。
image
就会生成:DataSetProjects.cs文件(当然你要选择显示所有文件,不然你怎么看到),查看代码如下:

public class DataSetProjects : DataSet {}

这样我们就得到了强类型DataSet:DataSetProjects了。
选择DataSetProjects.xsd属性
image 
你会看到自定义工具:MSDataSetGenerator,其实生成数据集就是使用它。

接下来我们就来使用下它吧!
Web服务Service1.asmx中添加Web方法:GetProjects()

using  System;
using  System.ComponentModel;
using  System.Data;
using  System.Data.SqlClient;
using  System.Web;
using  System.Web.Services;

namespace  WebService1
{
    
/// <summary>
    
/// Service1 的摘要说明。
    
/// </summary>

    public class Service1 : System.Web.Services.WebService
    
{
        
private SqlConnection _conn;
        
private SqlDataAdapter _daProjects;
        
private SqlCommand _selectCommand;

        
public Service1()
        
{
           
//CODEGEN: 该调用是 ASP.NET Web 服务设计器所必需的
            InitializeComponent();
        }


        
组件设计器生成的代码

        [WebMethod(Description
="Returns a project DataSet containing exactly one table named 'Projects'.")]
        
public DataSetProjects GetProjects()
        
{
            DataSetProjects ds 
= new DataSetProjects();
            _daProjects.Fill(ds, 
"Projects");
    
            
return ds;
        }

    }

}

运行我们可以对Web服务Service1.asmx中的Web方法:GetProjects进行调用测试:
image
调用将输出一个XML,代码如下:
返回的是强类型DataSet:DataSetProjects怎么为变成XML呢?
Web服务是以XML为基础,传输都是使用标准的XML,所以Web服务会将传输的对象序列化为XML,DataSetProjects继承DataSet,DataSet是可序列化的所以DataSetProjects也是可序列化的。程序引用Web服务,Web服务代理接收到XML文件会自动反序列为原来的对象方便调用,使你感觉不到调用Web服务与调用其它函数有什么不同之处。
<? xml version="1.0" encoding="utf-8" ?>
< DataSetProjects  xmlns ="http://tempuri.org/" >
  
< xs:schema  id ="DataSetProjects"  
    targetNamespace
="http://tempuri.org/DataSetProjects.xsd"  
    xmlns:mstns
="http://tempuri.org/DataSetProjects.xsd"  
    xmlns
="http://tempuri.org/DataSetProjects.xsd"  
    xmlns:xs
="http://www.w3.org/2001/XMLSchema"  
    xmlns:msdata
="urn:schemas-microsoft-com:xml-msdata"  
    attributeFormDefault
="qualified"  
    elementFormDefault
="qualified" >
    
< xs:element  name ="DataSetProjects"  
        msdata:IsDataSet
="true"  msdata:Locale ="zh-CN" >
      
< xs:complexType >
        
< xs:choice  minOccurs ="0"  maxOccurs ="unbounded" >
          
< xs:element  name ="Projects" >
            
< xs:complexType >
              
< xs:sequence >
                
< xs:element  name ="ProjectID"  
                    msdata:ReadOnly
="true"  msdata:AutoIncrement ="true"  type ="xs:int"   />
                
< xs:element  name ="ProjectName"  type ="xs:string"   />
                
< xs:element  name ="ProjectDescription"  type ="xs:string"   />
                
< xs:element  name ="DateCreated"  type ="xs:dateTime"   />
              
</ xs:sequence >
            
</ xs:complexType >
          
</ xs:element >
        
</ xs:choice >
      
</ xs:complexType >
      
< xs:unique  name ="DocumentKey1"  msdata:PrimaryKey ="true" >
        
< xs:selector  xpath =".//mstns:Projects"   />
        
< xs:field  xpath ="mstns:ProjectID"   />
      
</ xs:unique >
    
</ xs:element >
  
</ xs:schema >
  
< diffgr:diffgram 
    
xmlns:msdata ="urn:schemas-microsoft-com:xml-msdata"  
    xmlns:diffgr
="urn:schemas-microsoft-com:xml-diffgram-v1" >
    
< DataSetProjects  xmlns ="http://tempuri.org/DataSetProjects.xsd" >
      
< Projects  diffgr:id ="Projects1"  msdata:rowOrder ="0" >
        
< ProjectID > 1 </ ProjectID >
        
< ProjectName > Acme </ ProjectName >
        
< ProjectDescription > This is a test project. </ ProjectDescription >
        
< DateCreated > 2003-01-02T06:29:05.42+08:00 </ DateCreated >
      
</ Projects >
      
< Projects  diffgr:id ="Projects2"  msdata:rowOrder ="1" >
        
< ProjectID > 2 </ ProjectID >
        
< ProjectName > Microsoft </ ProjectName >
        
< ProjectDescription > This is a test project. </ ProjectDescription >
        
< DateCreated > 2003-01-02T06:29:05.513+08:00 </ DateCreated >
      
</ Projects >
    
</ DataSetProjects >
  
</ diffgr:diffgram >
</ DataSetProjects >
针对这个例子我们来说说强类型DataSet与非DataSet的区别:我们需要取得表Projects第一行记录ProjectName的值。
针对非类型DataSet:
[WebMethod]
public   string  GetProjectName()
{
    DataSet ds 
= new DataSet();
    _daProjects.Fill(ds,
"Projects");

    
return ds.Tables["Projects"].Rows[0]["ProjectName"].ToString();            
}
调用该Web方法返回:
<?xml version="1.0" encoding="utf-8" ?>
<string xmlns="http://tempuri.org/">Acme</string> 
从上面可以看出非类型DataSet:ds.Tables[ "Projects"].Rows[0][ "ProjectName"]返回的是object类型。我们需要强转换。
我们需要拼写正确的字段名,如果把ProjectName拼写成ProjectNane的话,我们需要在运行时才会提示错误。

针对强类型DataSet:
[WebMethod]
public   string  GetProjectName()
{
    DataSetProjects ds 
= new DataSetProjects();
    _daProjects.Fill(ds, 
"Projects");
    
    
return ds.Projects[0].ProjectName;       
}
调用该Web方法返回和上面一样的结果。
ds.Projects[0].ProjectName;返回类型直接就是ProjectName的类型string,无需我们强转换。ProjectName如果我们拼写成ProjectNane那么编译就会产生错误。

我们来使用DataTable的Find方法来实现GetProjectName可以更清晰的看出区别:
针对非类型DataSet:
[WebMethod]
public   string  GetProjectName()
{
  DataSet ds 
= new DataSet();
  _daProjects.Fill(ds,
"Projects");

  DataTable tbl 
= ds.Tables["Projects"];
  tbl.PrimaryKey 
= new DataColumn[]{tbl.Columns["ProjectID"]};//定义主键

  DataRow row 
= tbl.Rows.Find(1);//ProjectID=1

  
return row["ProjectName"].ToString();
要想使用DataTable的Find方法必须定义主键。
针对强类型由于xsd中已经定义好了主键,所以无需我们在程序中定义而且还有更清晰的方法:
[WebMethod]
public   string  GetProjectName()
{
  DataSetProjects ds 
= new DataSetProjects();
  _daProjects.Fill(ds, 
"Projects");

  
return ds.Projects.FindByProjectID(1).ProjectName;//ProjectID=1
}
从上面的两个例子可以看出强类型DataSet给我们带来非常大的方便。
强类型对应的方法和属性都可以在DataSetProjects.cs文件中找到。class DataSetProjects类中
比如上面用到的方法:
public  ProjectsRow FindByProjectID( int  ProjectID)  {
  
return ((ProjectsRow)(this.Rows.Find(new object[] {
                            ProjectID}
)));
}
所以你也可以看到,其实就是把非类型的DataSet的操作进行封装。

(三)使用vs2003创建数据集,生成强类型DataSet 
使用vs2003创建一个Asp.Net Web服务,添加新项:选择数据集:名称DataSetProjects.xsd
小菜上面说过一句话:添加新项:选择XML架构(注意不是数据集,下面会讲到)现在就讲到了。
和之前的一样,添加到TaskVision数据库的连接,打开DataSetProjects.xsd然后把Projects表拉入。
直接就得到下图:
image
我们不需要显示:IsDeleted,把其删除。
显示所有文件,我们会看到,我们已经有了一个:DataSetProjects.cs查看代码如下:
public class DataSetProjects : DataSet {}

噢,苍天啊大地啊,这么方便!(其实就是vs2003帮你做了之前你所做的那些事。)
如果一开始就和你讲这么简单的实现的话,那么你一定没有心思看上面那么复杂的创建过程(其实一点也不复杂)。而且直接和你说下面一种方式,你什么也没学到,只是学到添加新项,选择数据集,而已,仅此而已。
至于为什么要说上面那个复杂的过程,因为在vs2005里,可没有这么便宜的事。连上面那个复杂的过程你也别想有。不信啊,你就接着往下看,

(四)、使用vs2005 XML架构生成强类型DataSet
接下来进入你的痛苦旅程:在vs2005中实现和上述同样的功能。
上面的实现就是TaskVision中的实现,不过毕竟TaskVision是在vs2002中创建的,我们的最终目的,当然是移植到vs2005,并且利用vs2005的特性。

在vs2005中创建一个Asp.Net Web服务
添加新项,同样是选择XML架构,而不是数据集。(同样至于为何,下面会讲到。)
添加到TaskVision数据库的连接,打开DataSetProjects.xsd然后把Projects表拉入。
如下图所示:
image
和在vs2003中生成的一样,不过方向倒了,颜色换了而已,脱了马甲,我们还是认得它。
1、我们不想显示IsDeleted,把它删掉。
2、Document名称不直观,把它改成DataSetProjects
3、将DataSetProjects属性IsDataSet设为true。(很遗憾的告诉你,没有这个属性,虽然在vs2003中有这个东西,可是vs2005中没有。)
怎么办呢?我们可以比较下这次的XML代码和之前使用vs2003中生成的XML代码的区别就可以很快找到答案。
vs2003中:<xs:element name="DataSetProjects" msdata:IsDataSet="true" msdata:Locale="zh-CN">
vs2005中:  <xs:element name="DataSetProjects">
所以呢!!!加上msdata:IsDataSet="true"吧。
重新打开DataSetProjects.xsd如下图:
image
接下来使用这个XML Schema来生成强类型DataSet:DataSetProjects。
在vs2003中多方便啊,小菜至今还在回味,右键,生成数据集,在vs2005中也试一下吧。
右键如下图:
image 
噢,生成数据集的按钮跑哪去了呢?怎么办啊,急死我了。(很遗憾的告诉你,没有。)
那怎么办呢?难道就这样放弃?不行,小菜可不轻言放弃。
小菜记起,在上面vs2003中生成数据集的时候。可以使用自定义工具:MSDataSetGenerator,来生成数据集。
点击DataSetProjects.xsd属性如下图:
image
怎么自定义工具也没有了,唉,微软vs2005,你有必要这么绝情吗?(注意了,其实Windows项目中属性有自定义工具,你输入MSDataGenerator就可以生成DataSetProjects.cs文件了,不过在Asp.Net Web服务和Asp.Net站点中属性中是没有自定工具这个选项的)

不过:上有政策,下有对策。
我们可以使用xsd.exe来生成DataSetProjects.cs文件。
xsd.exe在哪呢?你可以使用windows搜索一下。小菜的电脑上装有vs2003和vs2005所以有两个。
D:/Program Files/Microsoft Visual Studio .NET 2003/SDK/v1.1/Bin/xsd.exe(vs2003中的v1.1)
D:/Program Files/Microsoft Visual Studio 8/SDK/v2.0/Bin/xsd.exe(vs2005中的v2.0)

注意了,小菜不是让你运行它们,不过运行也没事,反正你也运行不了。:)
开始-》所有程序-》Microsoft .NET Framework SDK v2.0-》SDK命令提示
输入命令:xsd /dataset /language:cs "DataSetProjects.xsd的路径" /o:"DataSetProjects.cs输出的路径"
如下图:
 image
成功生成了DataSetProjects.cs文件了,如下图:
 image
查看DataSetProjects.cs代码:

public partial class DataSetProjects : System.Data.DataSet {}

我们成功得到了强类型DataSet:DataSetProjects
接下来同样在我们的Web服务中使用DataSetProjects

using  System;
using  System.Data;
using  System.Data.SqlClient;
using  System.Web;
using  System.Web.Services;
using  System.Web.Services.Protocols;

[WebService(Namespace 
=   " http://tempuri.org/ " )]
[WebServiceBinding(ConformsTo 
=  WsiProfiles.BasicProfile1_1)]
public   class  Service : System.Web.Services.WebService
{
    
private SqlConnection _conn;
    
private SqlDataAdapter _daProjects;
    
private SqlCommand _selectCommand;

    
public Service () {

        
//如果使用设计的组件,请取消注释以下行 
        
//InitializeComponent(); 

        _conn 
= new SqlConnection("Data Source=(local);Initial Catalog=TaskVision;User ID=sa;Password=password;");
        _daProjects 
= new SqlDataAdapter();

        _selectCommand 
= new SqlCommand();
        _selectCommand.Connection 
= _conn;
        _selectCommand.CommandText 
= "SELECT ProjectID, ProjectName, ProjectDescription, DateCreated FROM Projects WHERE (IsDeleted = 0)";

        _daProjects.SelectCommand 
= _selectCommand;
    }


    [WebMethod]
    
public string HelloWorld() {
        
return "Hello World";
    }


    [WebMethod(Description 
= "Returns a project DataSet containing exactly one table named 'Projects'.")]
    
public DataSetProjects GetProjects()
    
{
        DataSetProjects ds 
= new DataSetProjects();
        _daProjects.Fill(ds, 
"Projects");

        
return ds;
    }

}

运行一下,噢,错误    1    找不到类型或命名空间名称“DataSetProjects”(是否缺少 using 指令或程序集引用?)   
傻瓜错误,不过确有很多人犯,把DataSetProjects.cs放入App_Code文件夹中。就可以了。
所以在之前的生成命令中,我们可以直接指定DataSetProjects.cs输出到App_Code文件夹下,我们就省了麻烦。

好成功了!

我想到这里你还没有感觉到强类型DataSet的缺点吧!现在就让你感受一下吧。
还记得在(二)中使用的如下代码吗
[WebMethod]
public   string  GetProjectName()
{
  DataSetProjects ds 
= new DataSetProjects();
  _daProjects.Fill(ds, 
"Projects");

  
return ds.Projects.FindByProjectID(1).ProjectName;//ProjectID=1
}
量是在这里无效会出现错误,提示错误,找不到主键,之前已经说过了使用Find方法必须具有主键。
但这里为什么没有主键呢?我们可以查看DataSetProjects.xsd的XML代码。
<? xml version="1.0" encoding="utf-8" ?>
< xs:schema  id ="DataSetProjects"
    targetNamespace
="http://tempuri.org/XMLSchema.xsd"
    elementFormDefault
="qualified"
    xmlns
="http://tempuri.org/XMLSchema.xsd"
    xmlns:mstns
="http://tempuri.org/XMLSchema.xsd"
    xmlns:xs
="http://www.w3.org/2001/XMLSchema"
    xmlns:msdata
="urn:schemas-microsoft-com:xml-msdata" >
  
< xs:element  name ="DataSetProjects"  msdata:IsDataSet ="true" >
    
< xs:complexType >
      
< xs:choice  minOccurs ="0"  maxOccurs ="unbounded" >
        
< xs:element  name ="Projects" >
          
< xs:complexType >
            
< xs:sequence >
              
< xs:element  name ="ProjectID"  type ="xs:int"   />
              
< xs:element  name ="ProjectName"  type ="xs:string"   />
              
< xs:element  name ="ProjectDescription"  type ="xs:string"   />
              
< xs:element  name ="DateCreated"  type ="xs:dateTime"   />
            
</ xs:sequence >
          
</ xs:complexType >
        
</ xs:element >
      
</ xs:choice >
    
</ xs:complexType >
    
< xs:unique  name ="DocumentKey1" >
      
< xs:selector  xpath =".//mstns:Projects"   />
      
< xs:field  xpath ="mstns:ProjectID"   />
    
</ xs:unique >
  
</ xs:element >
</ xs:schema >
在上面的XML代码中,我们只看到了为ProjectID定义的唯一性约束,而没有为其定义主键PrimaryKey。
所以vs2005与vs2003自动产生的代码是不一样的。让我们对其修改代码如下:
<? xml version="1.0" encoding="utf-8" ?>
< xs:schema  id ="DataSetProjects"
    targetNamespace
="http://tempuri.org/DataSetProjects.xsd"
    xmlns:mstns
="http://tempuri.org/DataSetProjects.xsd"
    xmlns
="http://tempuri.org/DataSetProjects.xsd"
    xmlns:xs
="http://www.w3.org/2001/XMLSchema"
    xmlns:msdata
="urn:schemas-microsoft-com:xml-msdata"
    attributeFormDefault
="qualified"
    elementFormDefault
="qualified" >
  
< xs:element  name ="DataSetProjects"  msdata:IsDataSet ="true"  msdata:Locale ="en-US" >
    
< xs:complexType >
      
< xs:choice  minOccurs ="0"  maxOccurs ="unbounded" >
        
< xs:element  name ="Projects" >
          
< xs:complexType >
            
< xs:sequence >
              
< xs:element  name ="ProjectID"  msdata:ReadOnly ="true"
                    msdata:AutoIncrement
="true"  type ="xs:int"   />
              
< xs:element  name ="ProjectName"  type ="xs:string"   />
              
< xs:element  name ="ProjectDescription"  type ="xs:string"   />
              
< xs:element  name ="DateCreated"  type ="xs:dateTime"   />
            
</ xs:sequence >
          
</ xs:complexType >
        
</ xs:element >
      
</ xs:choice >
    
</ xs:complexType >
    
< xs:unique  name ="DataSetProjectsKey1"  msdata:PrimaryKey ="true" >
      
< xs:selector  xpath =".//mstns:Projects"   />
      
< xs:field  xpath ="mstns:ProjectID"   />
    
</ xs:unique >
  
</ xs:element >
</ xs:schema >
现在XML架构改变了,我们需要使用xsd.exe重新生成强类型DataSet:DataSetProjects。
如果你已经在本地应用程序引用了Web服务,使用该强类型DataSet:DataSetProjects,则需要更新Web服务的引用。可见XML架构的稳定对强类型DataSet来说非常重要,否则上面的重复过程也够你烦的。

(五)、使用vs2005 数据集生成强类型DataSet
vs2005提供的数据集功能非常的强大,特别是TableAdapter。
不过有正就有反,功能强大了,附加的代码也就多了,微软自动生成的代码目标当然是最通用的代码,而不是最适合你的代码。所以小菜现在还是比较倾向(四)、使用vs2005 XML架构生成强类型DataSet。

不过了解一下还是有必要的,这样才能更好的对比。而且自动生成的代码也可以参考。

同样在vs2005中创建一个Asp.Net Web服务。
1、添加数据集:DataSetProjects.xsd
2、会弹出TableAdapter配置向导让你选择数据库连接,直接取消。因为下面当我们直接拉入Projects表的时候就会自动生成。
3、把表Projects拉入,如下图
image 
删除IsDeleted。
vs2005默认帮我们创建了ProjectsTableAdapter,而且这是个功能最全的ProjectsTableAdapter,因为微软认为应该给你提供最完整的功能。
接下来我们就来使用一下吧。
using  System;
using  System.Web;
using  System.Web.Services;
using  System.Web.Services.Protocols;

[WebService(Namespace 
=   " http://tempuri.org/ " )]
[WebServiceBinding(ConformsTo 
=  WsiProfiles.BasicProfile1_1)]
public   class  Service : System.Web.Services.WebService
{
    
public Service () {

        
//如果使用设计的组件,请取消注释以下行 
        
//InitializeComponent(); 
    }


    [WebMethod]
    
public string HelloWorld() {
        
return "Hello World";
    }


    [WebMethod(Description 
= "Returns a project DataSet containing exactly one table named 'Projects'.")]
    
public DataSetProjects GetProjects()
    
{
        DataSetProjects ds 
= new DataSetProjects();

        DataSetProjectsTableAdapters.ProjectsTableAdapter adapter 
= new DataSetProjectsTableAdapters.ProjectsTableAdapter();
        adapter.Fill(ds.Projects);

        
return ds;
    }

}

不要惊慌,你看到的代码是真的。我们做了些什么,我们什么也没做。VS2005帮你都做了。
别人帮你做的太多了,会让我有点无所适从,因为我不清楚别人帮我做了些什么,怎么办呢?看看源码啊!
所有的代码都在DataSetProjects.xsd中:

<? xml version="1.0" encoding="utf-8" ?>
< xs:schema  id ="DataSetProjects"  targetNamespace ="http://tempuri.org/DataSetProjects.xsd"  xmlns:mstns ="http://tempuri.org/DataSetProjects.xsd"  xmlns ="http://tempuri.org/DataSetProjects.xsd"  xmlns:xs ="http://www.w3.org/2001/XMLSchema"  xmlns:msdata ="urn:schemas-microsoft-com:xml-msdata"  xmlns:msprop ="urn:schemas-microsoft-com:xml-msprop"  attributeFormDefault ="qualified"  elementFormDefault ="qualified" >
  
< xs:annotation >
    
< xs:appinfo  source ="urn:schemas-microsoft-com:xml-msdatasource" >
      
< DataSource  DefaultConnectionIndex ="0"  FunctionsComponentName ="QueriesTableAdapter"  Modifier ="AutoLayout, AnsiClass, Class, Public"  SchemaSerializationMode ="IncludeSchema"  xmlns ="urn:schemas-microsoft-com:xml-msdatasource" >
        
< Connections >
          
< Connection  AppSettingsObjectName ="Web.config"  AppSettingsPropertyName ="TaskVisionConnectionString"  ConnectionStringObject =""  IsAppSettingsProperty ="True"  Modifier ="Assembly"  Name ="TaskVisionConnectionString (Web.config)"  ParameterPrefix ="@"  PropertyReference ="AppConfig.System.Configuration.ConfigurationManager.0.ConnectionStrings.TaskVisionConnectionString.ConnectionString"  Provider ="System.Data.SqlClient" >
          
</ Connection >
        
</ Connections >
        
< Tables >
          
< TableAdapter  BaseClass ="System.ComponentModel.Component"  DataAccessorModifier ="AutoLayout, AnsiClass, Class, Public"  DataAccessorName ="ProjectsTableAdapter"  GeneratorDataComponentClassName ="ProjectsTableAdapter"  Name ="Projects"  UserDataComponentName ="ProjectsTableAdapter" >
            
< MainSource >
              
< DbSource  ConnectionRef ="TaskVisionConnectionString (Web.config)"  DbObjectName ="TaskVision.dbo.Projects"  DbObjectType ="Table"  FillMethodModifier ="Public"  FillMethodName ="Fill"  GenerateMethods ="Both"  GenerateShortCommands ="True"  GeneratorGetMethodName ="GetData"  GeneratorSourceName ="Fill"  GetMethodModifier ="Public"  GetMethodName ="GetData"  QueryType ="Rowset"  ScalarCallRetval ="System.Object, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"  UseOptimisticConcurrency ="True"  UserGetMethodName ="GetData"  UserSourceName ="Fill" >
                
< DeleteCommand >
                  
< DbCommand  CommandType ="Text"  ModifiedByUser ="False" >
                    
< CommandText > DELETE FROM [Projects] WHERE (([ProjectID] = @Original_ProjectID) AND ([ProjectName] = @Original_ProjectName) AND ([ProjectDescription] = @Original_ProjectDescription) AND ([DateCreated] = @Original_DateCreated)) </ CommandText >
                    
< Parameters >
                      
< Parameter  AllowDbNull ="False"  AutogeneratedName =""  DataSourceName =""  DbType ="Int32"  Direction ="Input"  ParameterName ="@Original_ProjectID"  Precision ="0"  ProviderType ="Int"  Scale ="0"  Size ="0"  SourceColumn ="ProjectID"  SourceColumnNullMapping ="False"  SourceVersion ="Original" >
                      
</ Parameter >
                      
< Parameter  AllowDbNull ="False"  AutogeneratedName =""  DataSourceName =""  DbType ="AnsiString"  Direction ="Input"  ParameterName ="@Original_ProjectName"  Precision ="0"  ProviderType ="VarChar"  Scale ="0"  Size ="0"  SourceColumn ="ProjectName"  SourceColumnNullMapping ="False"  SourceVersion ="Original" >
                      
</ Parameter >
                      
< Parameter  AllowDbNull ="False"  AutogeneratedName =""  DataSourceName =""  DbType ="AnsiString"  Direction ="Input"  ParameterName ="@Original_ProjectDescription"  Precision ="0"  ProviderType ="VarChar"  Scale ="0"  Size ="0"  SourceColumn ="ProjectDescription"  SourceColumnNullMapping ="False"  SourceVersion ="Original" >
                      
</ Parameter >
                      
< Parameter  AllowDbNull ="False"  AutogeneratedName =""  DataSourceName =""  DbType ="DateTime"  Direction ="Input"  ParameterName ="@Original_DateCreated"  Precision ="0"  ProviderType ="DateTime"  Scale ="0"  Size ="0"  SourceColumn ="DateCreated"  SourceColumnNullMapping ="False"  SourceVersion ="Original" >
                      
</ Parameter >
                    
</ Parameters >
                  
</ DbCommand >
                
</ DeleteCommand >
                
< InsertCommand >
                  
< DbCommand  CommandType ="Text"  ModifiedByUser ="False" >
                    
< CommandText > INSERT INTO [Projects] ([ProjectName], [ProjectDescription], [DateCreated]) VALUES (@ProjectName, @ProjectDescription, @DateCreated);
SELECT ProjectID, ProjectName, ProjectDescription, DateCreated FROM Projects WHERE (ProjectID = SCOPE_IDENTITY())
</ CommandText >
                    
< Parameters >
                      
< Parameter  AllowDbNull ="False"  AutogeneratedName =""  DataSourceName =""  DbType ="AnsiString"  Direction ="Input"  ParameterName ="@ProjectName"  Precision ="0"  ProviderType ="VarChar"  Scale ="0"  Size ="0"  SourceColumn ="ProjectName"  SourceColumnNullMapping ="False"  SourceVersion ="Current" >
                      
</ Parameter >
                      
< Parameter  AllowDbNull ="False"  AutogeneratedName =""  DataSourceName =""  DbType ="AnsiString"  Direction ="Input"  ParameterName ="@ProjectDescription"  Precision ="0"  ProviderType ="VarChar"  Scale ="0"  Size ="0"  SourceColumn ="ProjectDescription"  SourceColumnNullMapping ="False"  SourceVersion ="Current" >
                      
</ Parameter >
                      
< Parameter  AllowDbNull ="False"  AutogeneratedName =""  DataSourceName =""  DbType ="DateTime"  Direction ="Input"  ParameterName ="@DateCreated"  Precision ="0"  ProviderType ="DateTime"  Scale ="0"  Size ="0"  SourceColumn ="DateCreated"  SourceColumnNullMapping ="False"  SourceVersion ="Current" >
                      
</ Parameter >
                    
</ Parameters >
                  
</ DbCommand >
                
</ InsertCommand >
                
< SelectCommand >
                  
< DbCommand  CommandType ="Text"  ModifiedByUser ="False" >
                    
< CommandText > SELECT ProjectID, ProjectName, ProjectDescription, DateCreated FROM Projects </ CommandText >
                    
< Parameters >
                    
</ Parameters >
                  
</ DbCommand >
                
</ SelectCommand >
                
< UpdateCommand >
                  
< DbCommand  CommandType ="Text"  ModifiedByUser ="False" >
                    
< CommandText > UPDATE [Projects] SET [ProjectName] = @ProjectName, [ProjectDescription] = @ProjectDescription, [DateCreated] = @DateCreated WHERE (([ProjectID] = @Original_ProjectID) AND ([ProjectName] = @Original_ProjectName) AND ([ProjectDescription] = @Original_ProjectDescription) AND ([DateCreated] = @Original_DateCreated));
SELECT ProjectID, ProjectName, ProjectDescription, DateCreated FROM Projects WHERE (ProjectID = @ProjectID)
</ CommandText >
                    
< Parameters >
                      
< Parameter  AllowDbNull ="False"  AutogeneratedName =""  DataSourceName =""  DbType ="AnsiString"  Direction ="Input"  ParameterName ="@ProjectName"  Precision ="0"  ProviderType ="VarChar"  Scale ="0"  Size ="0"  SourceColumn ="ProjectName"  SourceColumnNullMapping ="False"  SourceVersion ="Current" >
                      
</ Parameter >
                      
< Parameter  AllowDbNull ="False"  AutogeneratedName =""  DataSourceName =""  DbType ="AnsiString"  Direction ="Input"  ParameterName ="@ProjectDescription"  Precision ="0"  ProviderType ="VarChar"  Scale ="0"  Size ="0"  SourceColumn ="ProjectDescription"  SourceColumnNullMapping ="False"  SourceVersion ="Current" >
                      
</ Parameter >
                      
< Parameter  AllowDbNull ="False"  AutogeneratedName =""  DataSourceName =""  DbType ="DateTime"  Direction ="Input"  ParameterName ="@DateCreated"  Precision ="0"  ProviderType ="DateTime"  Scale ="0"  Size ="0"  SourceColumn ="DateCreated"  SourceColumnNullMapping ="False"  SourceVersion ="Current" >
                      
</ Parameter >
                      
< Parameter  AllowDbNull ="False"  AutogeneratedName =""  DataSourceName =""  DbType ="Int32"  Direction ="Input"  ParameterName ="@Original_ProjectID"  Precision ="0"  ProviderType ="Int"  Scale ="0"  Size ="0"  SourceColumn ="ProjectID"  SourceColumnNullMapping ="False"  SourceVersion ="Original" >
                      
</ Parameter >
                      
< Parameter  AllowDbNull ="False"  AutogeneratedName =""  DataSourceName =""  DbType ="AnsiString"  Direction ="Input"  ParameterName ="@Original_ProjectName"  Precision ="0"  ProviderType ="VarChar"  Scale ="0"  Size ="0"  SourceColumn ="ProjectName"  SourceColumnNullMapping ="False"  SourceVersion ="Original" >
                      
</ Parameter >
                      
< Parameter  AllowDbNull ="False"  AutogeneratedName =""  DataSourceName =""  DbType ="AnsiString"  Direction ="Input"  ParameterName ="@Original_ProjectDescription"  Precision ="0"  ProviderType ="VarChar"  Scale ="0"  Size ="0"  SourceColumn ="ProjectDescription"  SourceColumnNullMapping ="False"  SourceVersion ="Original" >
                      
</ Parameter >
                      
< Parameter  AllowDbNull ="False"  AutogeneratedName =""  DataSourceName =""  DbType ="DateTime"  Direction ="Input"  ParameterName ="@Original_DateCreated"  Precision ="0"  ProviderType ="DateTime"  Scale ="0"  Size ="0"  SourceColumn ="DateCreated"  SourceColumnNullMapping ="False"  SourceVersion ="Original" >
                      
</ Parameter >
                      
< Parameter  AllowDbNull ="False"  AutogeneratedName ="ProjectID"  ColumnName ="ProjectID"  DataSourceName ="TaskVision.dbo.Projects"  DataTypeServer ="int"  DbType ="Int32"  Direction ="Input"  ParameterName ="@ProjectID"  Precision ="0"  ProviderType ="Int"  Scale ="0"  Size ="4"  SourceColumn ="ProjectID"  SourceColumnNullMapping ="False"  SourceVersion ="Current" >
                      
</ Parameter >
                    
</ Parameters >
                  
</ DbCommand >
                
</ UpdateCommand >
              
</ DbSource >
            
</ MainSource >
            
< Mappings >
              
< Mapping  SourceColumn ="ProjectID"  DataSetColumn ="ProjectID"   />
              
< Mapping  SourceColumn ="ProjectName"  DataSetColumn ="ProjectName"   />
              
< Mapping  SourceColumn ="ProjectDescription"  DataSetColumn ="ProjectDescription"   />
              
< Mapping  SourceColumn ="DateCreated"  DataSetColumn ="DateCreated"   />
            
</ Mappings >
            
< Sources >
            
</ Sources >
          
</ TableAdapter >
        
</ Tables >
        
< Sources >
        
</ Sources >
      
</ DataSource >
    
</ xs:appinfo >
  
</ xs:annotation >
  
< xs:element  name ="DataSetProjects"  msdata:IsDataSet ="true"  msdata:UseCurrentLocale ="true"  msprop:Generator_UserDSName ="DataSetProjects"  msprop:Generator_DataSetName ="DataSetProjects" >
    
< xs:complexType >
      
< xs:choice  minOccurs ="0"  maxOccurs ="unbounded" >
        
< xs:element  name ="Projects"  msprop:Generator_UserTableName ="Projects"  msprop:Generator_RowDeletedName ="ProjectsRowDeleted"  msprop:Generator_TableClassName ="ProjectsDataTable"  msprop:Generator_RowChangedName ="ProjectsRowChanged"  msprop:Generator_RowClassName ="ProjectsRow"  msprop:Generator_RowChangingName ="ProjectsRowChanging"  msprop:Generator_RowEvArgName ="ProjectsRowChangeEvent"  msprop:Generator_RowEvHandlerName ="ProjectsRowChangeEventHandler"  msprop:Generator_TablePropName ="Projects"  msprop:Generator_TableVarName ="tableProjects"  msprop:Generator_RowDeletingName ="ProjectsRowDeleting" >
          
< xs:complexType >
            
< xs:sequence >
              
< xs:element  name ="ProjectID"  msdata:ReadOnly ="true"  msdata:AutoIncrement ="true"  msprop:Generator_UserColumnName ="ProjectID"  msprop:Generator_ColumnPropNameInRow ="ProjectID"  msprop:Generator_ColumnVarNameInTable ="columnProjectID"  msprop:Generator_ColumnPropNameInTable ="ProjectIDColumn"  type ="xs:int"   />
              
< xs:element  name ="ProjectName"  msprop:Generator_UserColumnName ="ProjectName"  msprop:Generator_ColumnPropNameInRow ="ProjectName"  msprop:Generator_ColumnVarNameInTable ="columnProjectName"  msprop:Generator_ColumnPropNameInTable ="ProjectNameColumn" >
                
< xs:simpleType >
                  
< xs:restriction  base ="xs:string" >
                    
< xs:maxLength  value ="20"   />
                  
</ xs:restriction >
                
</ xs:simpleType >
              
</ xs:element >
              
< xs:element  name ="ProjectDescription"  msprop:Generator_UserColumnName ="ProjectDescription"  msprop:Generator_ColumnPropNameInRow ="ProjectDescription"  msprop:Generator_ColumnVarNameInTable ="columnProjectDescription"  msprop:Generator_ColumnPropNameInTable ="ProjectDescriptionColumn" >
                
< xs:simpleType >
                  
< xs:restriction  base ="xs:string" >
                    
< xs:maxLength  value ="100"   />
                  
</ xs:restriction >
                
</ xs:simpleType >
              
</ xs:element >
              
< xs:element  name ="DateCreated"  msprop:Generator_UserColumnName ="DateCreated"  msprop:Generator_ColumnPropNameInRow ="DateCreated"  msprop:Generator_ColumnVarNameInTable ="columnDateCreated"  msprop:Generator_ColumnPropNameInTable ="DateCreatedColumn"  type ="xs:dateTime"   />
            
</ xs:sequence >
          
</ xs:complexType >
        
</ xs:element >
      
</ xs:choice >
    
</ xs:complexType >
    
< xs:unique  name ="Constraint1"  msdata:PrimaryKey ="true" >
      
< xs:selector  xpath =".//mstns:Projects"   />
      
< xs:field  xpath ="mstns:ProjectID"   />
    
</ xs:unique >
  
</ xs:element >
</ xs:schema >

vs2005帮你生成了对于你选定的表提供最通过的sql语句:select,update,insert,delete。这些功能都有一个TableAdapter表适配器ProjectsTableAdapter提供。
ProjectsTableAdapter还有一个方法GetData()可以取得该表的数据。返回类型为DataSetProjects.ProjectsDataTable

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值