现在的位置: 首页 > 综合 > 正文

强类型DataSet与普通弱类型DataSet

2013年01月03日 ⁄ 综合 ⁄ 共 5412字 ⁄ 字号 评论关闭

DataSet属于弱类型,这意味着无论何时从 DataSet 中检索值,值都以 System.Object 的形式返回,你需要对这种值进行转换。不幸的是,失败不是在编译时发生,而是在运行时发生.

DataReader和普通的DataSet是弱类型对象,因为它们的schema是被用来填充它们的数据库查询返回的字段来定义的。要访问弱类型DataTable中的一个特定字段,我们需要用这样的句法:DataTable.Rows[index] ["columnName"]。这个例子中的DataTable的弱类型性质表现在于,我们需要通过一个字符串或序号索引来访问字段名称。而在另一个方面,一个强类型的DataTable,它的所有的字段都是通过属性的形式来实现的
,访问的编码就会象这样:DataTable.Rows[index].columnName。

要返回强类型对象,开发人员可以创建自定义业务对象,或者使用强类型的DataSet。开发人员实现的业务对 象类,其属性往往是对相应的底层数据表的字段的映射。而一个强类型的DataSet,则是Visual Studio基于数 据库schema为你生成的一个类,其成员的类型都是由这个schema决定的。强类型的DataSet本身,是由继承 于ADO.NET中DataSet,DataTable,和DataRow类的子类组成的。除了强类型的DataTable外,强类型的DataSet现在还包括TableAdapter类,这些类包含了填充DataSet中的DataTable和把
DataTable的改动传回数据库的各种方法。

“typed DataSet是从DataSet派生的,它根据事先定义的Data Schema生成数据集,对数据集中的字段实行强类型约束。你可以通过它产生的cs文件看到许多方法对DataTable的操作进行了封装,这样你就可以通过MyDataSet.MyTable.Field对字段进行访问,而不是像DataSet那样:

MyDataSet.Tables["TableName"]["Field"]; 简化了编程,同时不容易出错,想象一下如果在"Field"中拼错了字段名,那么编译器也不会检查出来,对于typed DataSet就不用了,如果你Field写错的话,那么马上就可以知道。

还有就是如果你在Typed DataSet包含多数据集,同时在XSD中对这些数据集建立关系和约束,那么Type DataSet会生成相应的方法来反映这些关系和约束。如果使用untyped DataSet,你需要自己做。

性能上的考虑:虽然Typed DataSet创建对象实例的时候比unTypede DataSet要多一些开销(时间和空间),但是在填充数据的时候要比untyped DataSet快,这是因为DataAdapter已经知道怎么Fill一个Typed DataSet,相比之下,DataSet需要两次读取数据库,第一次取得数据库中表的结构信息,第二次才fill数据。

Typed DataSet相对于DataSet的缺陷:除了创建的开销之外,Typed DataSet不如DataSet灵活,因为Typed DataSet一旦确定,数据表的结构就固定了,如果需要修改,必须重新生成。

而DataSet你可以随时根据需要进行操作(比如添加字段,删除字段等)。”

强类型DataSet与普通弱类型DataSet 【C】 - 蘭松 - 愛的記憶

上面一段话的出处不可考:)下面来看怎么用vs.net创建强类型DataSet

项目-添加新项-从弹出窗口中选择数据-选择数据集,然后起一个名字,点确定。现在就可以看到设计视图了。

下一步要做的就是打开服务器资源管理器,然后找到要创建到数据集里的数据表,把它拖到设计视图中,最后shift+ctrl+b生成,一个typed DataSet就创建完毕了。

很简单吧,现在可以看看typed DataSet的后台.cs代码,推荐使用类视图来快速查看该typed DataSet的详细内容。可以看到属性方法事件一应具全,在typed DataSet里包含的原ado.net的datatable/datarow/datacolumn都是以套嵌类的方式公开的,数据库里的字段以属性方式公开

下面是一个示例,通过填写序号和要修改的内容来修改数据库,演示了对typed DataSet属性方法事件的操作。

typedDataSet.aspx

<%@ Page language="c#" Codebehind="typedDataSet.aspx.cs" AutoEventWireup="false" Inherits="newCentury.typedDataSet" trace=true %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >

<HTML>

<HEAD>

<title>typedDataSet</title>

<meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">

<meta content="C#" name="CODE_LANGUAGE">

<meta content="JavaScript" name="vs_defaultClientScript">

<meta content=""'' intellisense schemas.microsoft.com>http://schemas.microsoft.com/intellisense/ie5& ... ot;vs_targetSchema">

</HEAD>

<body>

<form id="Form1" method="post" runat="server">

序号:<asp:TextBox id="idToDel" runat="server"></asp:TextBox>

新值:<asp:TextBox id="newMword" runat="server"></asp:TextBox>

<asp:Button id="go" runat="server" Text="delete!"></asp:Button>

</form>

</body>

</HTML>

typedDataSet.aspx.cs

using System;

using System.Collections;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Web;

using System.Web.SessionState;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.HtmlControls;

using System.Data.SqlClient;

using System.Configuration;

namespace newCentury

{

/// <summary>

/// typedDataSet 的摘要说明。

/// </summary>

public class typedDataSet : System.Web.UI.Page

{

//声明typedDataSet的实例

private myDS myds;

private SqlConnection conn;

private SqlCommand cmd;

private SqlCommand cmdUp;

private SqlDataAdapter ada;

protected System.Web.UI.WebControls.TextBox idToDel;

protected System.Web.UI.WebControls.TextBox newMword;

protected System.Web.UI.WebControls.Button go;

private void Page_Load(object sender, System.EventArgs e)

{

if(!Page.IsPostBack)

{

outPut();

}

}

#region Web 窗体设计器生成的代码

override protected void OnInit(EventArgs e)

{

//

// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。

//

InitializeComponent();

base.OnInit(e);

}

/// <summary>

/// 设计器支持所需的方法 - 不要使用代码编辑器修改

/// 此方法的内容。

/// </summary>

private void InitializeComponent()

{

this.go.Click += new System.EventHandler(this.go_Click);

this.Load += new System.EventHandler(this.Page_Load);

}

#endregion

private void setUp()

{

string connStr=ConfigurationSettings.AppSettings[0];

conn=new SqlConnection(connStr);

cmd=conn.CreateCommand();

cmd.CommandText="select * from [member]";

ada=new SqlDataAdapter();

ada.SelectCommand=cmd;

//创建实例

myds=new myDS();

}

private void outPut()

{

setUp();

try

{

//填充数据集,

注意datatable的名字一定要指定为typed DataSet中的名字

ada.Fill(myds,"member");

//获得datatable,注意获取的方法

myDS.memberDataTable mdt=myds.member;

//遍历

foreach(myDS.memberRow mr in mdt.Rows)

{

Response.Output.Write(mr.mid+" "+mr.mword+"<br>");

}

Response.Write(mdt.FindBymid(3).mname);

}

catch(SqlException ex)

{

Trace.Warn("sql error","outPut",ex);

}

catch(Exception ex)

{

Trace.Warn("comm error","outPut",ex);

}

finally

{

ada.Dispose();

}

}

private void go_Click(object sender, System.EventArgs e)

{

setUp();

cmdUp=conn.CreateCommand();

cmdUp.CommandText="update member set mword=@mword where mid=@mid";

cmdUp.Parameters.Add("@mword",SqlDbType.VarChar,20,"mword");

cmdUp.Parameters.Add("@mid",SqlDbType.Int,0,"mid");

ada.UpdateCommand=cmdUp;

try

{

ada.Fill(myds,"member");

myDS.memberDataTable mdt=myds.member;

mdt.RowChanged+=new DataRowChangeEventHandler(mdt_RowChanged);

//直接使用方法来获得要更新的行

myDS.memberRow mr=mdt.FindBymid(int.Parse(idToDel.Text));

Trace.Warn("in click handler before new mword",mr.RowState.ToString());

//更改也是使用属性来操作

mr.mword=newMword.Text;

Trace.Warn("in click handler after new mword",mr.RowState.ToString());

ada.Update(myds,"member");

Trace.Warn("in click handler after update method",mr.RowState.ToString());

foreach(myDS.memberRow dmr in mdt.Rows)

{

Response.Output.Write(dmr.mid+" "+dmr.mword+"<br>");

}

}

catch(SqlException ex)

{

Trace.Warn("sql error","outPut",ex);

}

catch(Exception ex)

{

Trace.Warn("comm error","outPut",ex);

}

finally

{

ada.Dispose();

}

}

//处理mdt_RowChanged事件的方法

private void mdt_RowChanged(object sender, DataRowChangeEventArgs e)

{

Trace.Warn("in mdt_RowChanged",e.Row.RowState.ToString());

}

}

}

抱歉!评论已关闭.