• DataGridView显示主从表示例及注意事项


    diyblPic
    在.NET 的Windows Forms数据处理应用中,经常需要处理主从表情况。例如:SQL Server 2000的Northwind数据库Custumers表和Orders表中,一个客户对应多个定单(用关系数据库理论的ER概念模型描述,客户实体与定 单实体是1:N的关系)。编程时,可以用一个DataGridView显示Customers记录(主表),另一个DataGridView显示当前 Customer的定单明细(从表)。当点选主表DataGridView的Customers记录时,从表DataGridView自动过滤显示对应 CustomerID的全部Orders记录(见上图)。C# 2005/2008中的BindingSource组件和DataSet/DataRelation类提供了一个简便的处理方法,见如下实现步骤和示例代 码。
    1. 建立一个DataSet数据集对象,使用DataAdaper填充两个DataTable表:Customers和Orders,分别包含全部的Customers记录和Orders记录。也可直接创建和填充数据表;
    2. 以Custumers的主键CustomerID和Orders的外键CustomerIdD建立一个主从DataRelation关系对象,并添加该对象到DataSet中;
    3. 使用两个BindingSource组件:bs_Customers和bs_Orders,分别连接表数据集DataSet的表Customers和关系DataRelation;
    4. 使用两个DataGridView组件,分别连接bs_Customers和bs_Orders。
    下面是全部程序示例代码,测试运行时须有SQL Server 2000的Northwind数据库,不使用数据库且直接创建数据表的代码参见本文最后给出的简例。using System;
    using System.Data;
    using System.Data.SqlClient;
    using System.Windows.Forms;

    namespace WindowsApplication1
    {
    public partial class Form1 : Form
    {
    public Form1()
    {
    InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
    SqlConnection conn = new SqlConnection();
    SqlConnectionStringBuilder ssb = new SqlConnectionStringBuilder();
    conn.ConnectionString =
    "Data Source=localhost; Initial Catalog=Northwind; Integrated Security = True;";
    conn.Open();

    DataSet dbSet = new DataSet(); // 创建数据集
    using (SqlDataAdapter da = new SqlDataAdapter("select * from Customers", conn))
    {
    da.Fill(dbSet, "Customers"); // 填充一个 Customers 表
    }
    using (SqlDataAdapter da = new SqlDataAdapter("select * from Orders", conn))
    {
    da.Fill(dbSet, "Orders"); // 填充一个 Orders 表
    }

    DataColumn parentCol = dbSet.Tables["Customers"].Columns["CustomerID"];
    DataColumn childCol = dbSet.Tables["Orders"].Columns["CustomerID"];
    DataRelation relation =
    new DataRelation("FK_Customers_Orders", parentCol, childCol); // 建立主从关系
    dbSet.Relations.Add(relation); // 添加主从关系到数据集中

    BindingSource bs_Customers = new BindingSource(); // 创建绑定源
    BindingSource bs_Orders = new BindingSource();

    bs_Customers.DataSource = dbSet;
    bs_Customers.DataMember = "Customers"; // 绑定到数据源——主表

    bs_Orders.DataSource = bs_Customers;
    bs_Orders.DataMember = "FK_Customers_Orders"; // 绑定到关系——从表,注意:区分大小写

    dataGridView1.DataSource = bs_Customers; // DataGridView 显示
    dataGridView2.DataSource = bs_Orders;
    }
    }
    }
    与主表的常规绑定方式不同,从表bs_Orders的数据源和数据成员的绑定技巧是:
    • http://msnpiki.msnfanatic.com/index.php/Main_Page-->
    • rgin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: disc; ">bs_Orders.DataSource = bs_Customers,即主表的BindingSource数据源;
    • bs_Orders.DataMember = "FK_Customers_Orders",即数据集dsSet中的主从关系名。
    特 别需要指出:当使用C#2005/2008编程时,从表bs_Orders的数据成员DataMember使用的关系名是区分大小写的。针对上面示例,如 果代码改为:DataMember = "fk_Customers_Orders",即修改"FK"为"fk",此时程序并不报错,并且主表第一条记录对应的从表记录是正确的!但浏览移动主表 记录时,从表对应的记录为空,即使主表移动到第一条记录时从表也为空!同时还需要指出如下几点:
    • 并不要求CustomerID是Customers的主键和Orders的外键,但要满足外键的基本条件——主表的CustomerID值唯一,从表的CustomerID值对应主表的某个值。见本文后面给出的程序代码;
    • 主从关系是通过数据集DataSet、数据关系DataRelation和数据源绑定组件BindingSource体现的,与显示控件无关。此时,可以使用ComboBox、ListBox等显示主从关系情况;
    • 主从关系中的数据表,还可以是定制的对象集,具体使用可以参考《Windows Forms 2.0数据绑定——.NET智能客户端数据应用程序设计》一书。
    事 实上,.NET通过字符串名称检索是其特性——索引器,即通过[]设置和访问对象,许多情况并不区分大小写,如:DataSet.Table[]、 DataGridViewColumns[]、BindingSource.DataMember(为数据表时)。为何C# 2005/2008中DataRelation的关系名区分大小写?或者是否是.NET的一个BUG?有兴趣者可以进一步探讨。下面是直接构建两个表的代码,取代前面从Northwind填充数据的两个using(){}语句组:private void Form1_Load(object sender, EventArgs e)
    {
    DataSet dbSet = new DataSet(); // 创建数据集

    DataTable customers = new DataTable("Customers"); // 创建客户表
    DataColumn dc = new DataColumn("CustomerID", typeof(int)); // 创建字段
    customers.Columns.Add(dc);
    customers.Rows.Add(1); // 添加两个记录
    customers.Rows.Add(2);

    DataTable orders = new DataTable("Orders"); // 创建定单表
    dc = new DataColumn("OrderId", typeof(int));
    orders.Columns.Add(dc);
    dc = new DataColumn("CustomerID", typeof(int));
    orders.Columns.Add(dc);

    orders.Rows.Add(1, 1); // 添加记录,注意:CustomerID必须与前面表的某个值相同
    orders.Rows.Add(2, 1); // 即要满足外键的条件
    orders.Rows.Add(3, 2);
    orders.Rows.Add(4, 2);

    dbSet.Tables.Add(customers);
    dbSet.Tables.Add(orders);

    // 接前面的代码部分
    }
  • 相关阅读:
    【原】ListView的BeginUpdate()和EndUpdate()的用处
    【原】Telerik radwindow 在IE10下偶尔报 unable to get value of the property 'toLowerCase' 的解决办法
    【原】从头学习设计模式(一)——单例模式
    【原】从头学习设计模式(二)——简单工厂模式
    【原】通过JS打开IE新tab(非Window)的解决方案
    【原】高效GTD云工具 ——高效管理你的时间
    【原】安装Win7和Ubuntu双系统后,Win7耳机无声音的解决办法
    【原】从头学习设计模式(三)——工厂方法模式
    【原】备忘:Oracle 中创建存储过程及调用测试一例
    【转】DBA的性格
  • 原文地址:https://www.cnblogs.com/top5/p/1552459.html
Copyright © 2020-2023  润新知