您的位置:首页精文荟萃软件资讯 → ADO.NET中的多数据表操作浅析之读取

ADO.NET中的多数据表操作浅析之读取

时间:2004/10/8 13:19:00来源:本站整理作者:蓝点我要评论(0)

  在开发基于.NET平台的数据库应用程序时,我们一般都会用到DataSet,作为ADO.NET的核心类它为我们提供了强大的功能,而整个看上去就像是放在内存内的一个小型数据库,内部包括了DataTable、DataView、DataRow、DataColumn、Constraint以及DataRelation。当初看到它时真的是有点兴奋。


  下面根据我的一些经验来举例说明在ADO.NET中的多表填充、关联表更新以及多个Command对象执行过程中启用事务的操作。欢迎大家交流,或在Blog上留言。


  一、准备工作


  对于NorthWind数据库大家都比较熟悉,所以这里拿它为例,我把Customers(客户表)、Orders(订单表)、Order Details(订单详细表)合起来建立了一个类型化的数据集,类型名称为DatasetOrders,每个表只包括一些字段,下面是在Visual Studio .NET中建立的一个截图:








图1-1



  上面建立了两个关系表示为Customers —> Orders —>Order Details。因为Orders表的OrderID字段为自动增长列,这里把就把它的AutoIncrementSeed和AutoIncrementStep值设置成了-1,这在实际添加订单的过程中可能会比较明显,不过不设也没问题。


  二.填充数据集

  建立一个窗体程序来演示实际的操作,界面如下:







图2-1

  整个应用程序就是一个Form,上面的三个DataGrid分别用来显示相关表的数据,不过他们是互动的。另外的两个单选框用来决定更新数据的方式,两个按钮正如他们的名称来完成相应的功能。

  这里我们用一个DataAdapter来完成数据集的填充,执行的存储过程如下:





CREATE PROCEDURE GetCustomerOrdersInfo

AS

SELECT CustomerID,CompanyName,ContactName FROM Customers WHERE CustomerID LIKE 'A%'

SELECT OrderID,OrderDate,CustomerID FROM Orders WHERE CustomerID IN
(SELECT CustomerID FROM Customers WHERE CustomerID LIKE 'A%')

SELECT OrderID,ProductID,UnitPrice,Quantity,Discount FROM [Order Details] WHERE OrderID IN
(SELECT OrderID FROM Orders WHERE CustomerID IN
(SELECT CustomerID FROM Customers WHERE CustomerID LIKE 'A%'))

GO

  为了减少数据量,这里只取了CustomerID以’A’开头的数据。建立DataAccess类来管理窗体同数据层的交互:





using System;
using System.Data;
using System.Data.SqlClient;
using Microsoft.ApplicationBlocks.Data;
namespace WinformTest
{
 public class DataAccess
 {
  private string _connstring = "data source=(local);initial catalog=Northwind;uid=csharp;pwd=c#.net2004;";
  private SqlConnection _conn;
  ///构造函数
  public DataAccess()
  {
   _conn = new SqlConnection(_connstring);
  }

  下面的函数完成单个数据适配器来完成数据集的填充,





public void FillCustomerOrdersInfo(DatasetOrders ds)
{
 SqlCommand comm = new SqlCommand("GetCustomerOrdersInfo",_conn);
 comm.CommandType = CommandType.StoredProcedure;
 SqlDataAdapter dataAdapter = new SqlDataAdapter(comm);
 dataAdapter.TableMappings.Add("Table","Customers");
 dataAdapter.TableMappings.Add("Table1","Orders");
 dataAdapter.TableMappings.Add("Table2","Order Details");
 dataAdapter.Fill(ds);
}


  如果使用SqlHelper来填充那就更简单了:





public void FillCustomerOrdersInfoWithSqlHelper(DatasetOrders ds)
{
SqlHelper.FillDataset(_connstring,CommandType.StoredProcedure,"GetCustomerOrdersInfo",ds,new string[]{"Customers","Orders","Order Details"});
}

  叉开话题提一下,Data Access Application Block 2.0中的SqlHelper.FillDataset这个方法超过两个表的填充时会出现错误,其实里面的逻辑是错的,只不过两个表的时候刚好凑巧,下面是从里面截的代码:





private static void FillDataset(SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, DataSet dataSet, string[] tableNames,
params SqlParameter[] commandParameters)

{
 if( connection == null ) throw new ArgumentNullException( "connection" );
 if( dataSet == null ) throw new ArgumentNullException( "dataSet" );
 SqlCommand command = new SqlCommand();
 bool mustCloseConnection = false;
 PrepareCommand(command, connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection );

 using( SqlDataAdapter dataAdapter = new SqlDataAdapter(command) )
 {
  if (tableNames != null && tableNames.Length > 0)
  {
   string tableName = "Table";
   for (int index=0; index < tableNames.Length; index++)
   {
    if( tableNames[index] == null || tableNames[index].Length == 0 )
     throw new ArgumentException( "The tableNames parameter must contain a list of tables, a value was  provided as null or empty string.", "tableNames" );

     tableName += (index + 1).ToString();//这里出现错误

   }
  }
  dataAdapter.Fill(dataSet);
  command.Parameters.Clear();
 }
 if( mustCloseConnection )
  connection.Close();
}

  这里把tableName += (index + 1).ToString();修改成





dataAdapter.TableMappings.Add((index>0) (tableName+index.ToString()):tableName, tableNames[index]);就能解决问题。

  接下来看看窗体程序的代码:





public class Form1 : System.Windows.Forms.Form
{
 private DataAccess _dataAccess;
 private DatasetOrders _ds;
 //……
 //构造函数
 public Form1()
 {
  InitializeComponent();
  _dataAccess = new DataAccess();
  _ds = new DatasetOrders();
  _ds.EnforceConstraints = false; //关闭约束检查,提高数据填充效率
  this.dataGridCustomers.DataSource = _ds;
  this.dataGridCustomers.DataMember = _ds.Customers.TableName;
  this.dataGridOrders.DataSource = _ds;
  this.dataGridOrders.DataMember = _ds.Customers.TableName+"."+_ds.Customers.ChildRelations[0].RelationName;
  this.dataGridOrderDetails.DataSource = _ds;
  this.dataGridOrderDetails.DataMember =_ds.Customers.TableName+"."+
    _ds.Customers.ChildRelations[0].RelationName+"."+
    _ds.Orders.ChildRelations[0].RelationName;
 }

  对于上面的三个表的动态关联,你也可以使用SetDataBinding方法来完成数据的动态绑定,而不是分别指定DataGride的DataSource和DataMemger属性。





this.dataGridCustomers.SetDataBinding(_ds,_ds.Customers.TableName);

this.dataGridOrders.SetDataBinding(_ds,_ds.Customers.TableName+"."+_ds.Customers.ChildRelations[0].RelationName);

this.dataGridOrderDetails.SetDataBinding(_ds,_ds.Customers.TableName+"."+
  _ds.Customers.ChildRelations[0].RelationName+"."+_ds.Orders.ChildRelations[0].RelationName);
}

  数据填充事件处理如下:





private void buttonFillData_Click(object sender, System.EventArgs e)
{
 _ds.Clear();//重新填充数据集
 _dataAccess.FillCustomerOrdersInfo(_ds);
 //_dataAccess.FillCustomerOrdersInfoWithSqlHelper(_ds);
}

  执行上面的事件处理函数我们会看到数据显示到对应的DataGrid上,如(图2-1)所示。

  如果使用数据读取器获取多表纪录下面是实现的一种方式(参考):





SqlCommand comm = new SqlCommand("GetCustomerOrdersInfo",_conn);
comm.CommandType = CommandType.StoredProcedure;
_conn.Open();
SqlDataReader reader = comm.ExecuteReader();
do
{
 while(reader.Read())
 {
  Console.WriteLine(reader[0].ToString());//获取数据代码
 }
}while(reader.NextResult());
Console.ReadLine();
_conn.Close();


相关阅读 Windows错误代码大全 Windows错误代码查询激活windows有什么用Mac QQ和Windows QQ聊天记录怎么合并 Mac QQ和Windows QQ聊天记录Windows 10自动更新怎么关闭 如何关闭Windows 10自动更新windows 10 rs4快速预览版17017下载错误问题Win10秋季创意者更新16291更新了什么 win10 16291更新内容windows10秋季创意者更新时间 windows10秋季创意者更新内容kb3150513补丁更新了什么 Windows 10补丁kb3150513是什么

文章评论
发表评论

热门文章 360快剪辑怎么使用 36金山词霸如何屏幕取词百度收购PPS已敲定!3

最新文章 微信3.6.0测试版更新了微信支付漏洞会造成哪 360快剪辑怎么使用 360快剪辑软件使用方法介酷骑单车是什么 酷骑单车有什么用Apple pay与支付宝有什么区别 Apple pay与贝贝特卖是正品吗 贝贝特卖网可靠吗

人气排行 xp系统停止服务怎么办?xp系统升级win7系统方电脑闹钟怎么设置 win7电脑闹钟怎么设置office2013安装教程图解:手把手教你安装与qq影音闪退怎么办 QQ影音闪退解决方法VeryCD镜像网站逐个数,电驴资料库全集同步推是什么?同步推使用方法介绍QQ2012什么时候出 最新版下载EDiary——一款好用的电子日记本