示例来自 MSDN,将四个表关联在一起,适应于在操作多表时,有时需要关联表有时不需要关联的情况下(见 CommunityServer 的 cs_shared_Threads_GetThreadSet 存储过程也属此类应用)。

using System;
using System.Data;
using System.Data.SqlClient;

namespace TestDataRelation
{

    class Program
    {
        static void Main()
        {
            PrintOrders("server=(local); uid=sa; pwd=; database=Test_DataSet_DataRelation");
        }

        private static void PrintOrders(string connectionString)
        {
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                DataSet customerOrders = new DataSet();

                connection.Open();

                SqlDataAdapter reader;

                reader = new SqlDataAdapter("SELECT * FROM Customers", connection);
                reader.Fill(customerOrders, "Customers");

                reader = new SqlDataAdapter("SELECT * FROM Orders", connection);
                reader.Fill(customerOrders, "Orders");

                reader = new SqlDataAdapter("SELECT * FROM OrderDetails", connection);
                reader.Fill(customerOrders, "OrderDetails");

                reader = new SqlDataAdapter("SELECT * FROM Products", connection);
                reader.Fill(customerOrders, "Products");

                connection.Close();

                DataRelation customerOrdersRelation = customerOrders.Relations.Add("CustOrders", customerOrders.Tables["Customers"].Columns["CustomerID"], customerOrders.Tables["Orders"].Columns["CustomerID"]);
                DataRelation orderDetailRelation = customerOrders.Relations.Add("OrderDetail", customerOrders.Tables["Orders"].Columns["OrderID"], customerOrders.Tables["OrderDetails"].Columns["OrderID"], false);
                DataRelation orderProductRelation = customerOrders.Relations.Add("OrderProducts", customerOrders.Tables["Products"].Columns["ProductID"], customerOrders.Tables["OrderDetails"].Columns["ProductID"]);

                // 打印所有订单及订单详情
                foreach (DataRow custRow in customerOrders.Tables["Customers"].Rows)
                {
                    Console.WriteLine("客户 ID: " + custRow["CustomerID"] + "\t客户姓名: " + custRow["CustomerName"]);
                    Console.WriteLine("----------------------------------------");

                    foreach (DataRow orderRow in custRow.GetChildRows(customerOrdersRelation))
                    {
                        Console.WriteLine("  订单号: " + orderRow["OrderID"]);
                        Console.WriteLine("\t订单日期: " + orderRow["OrderDate"]);

                        foreach (DataRow detailRow in orderRow.GetChildRows(orderDetailRelation))
                        {
                            Console.WriteLine("\t Product: " + detailRow.GetParentRow(orderProductRelation)["ProductName"]);
                            Console.WriteLine("\t Quantity: " + detailRow["Quantity"]);
                        }

                        Console.WriteLine();
                    }
                }

            }
        }
    }

}

MSDN:

请注意,当为 Customers 表和 Orders 表创建 DataRelation 时,没有为 createConstraints 标志指定任何值(默认为 true)。它假定 Orders 表中的所有行都具有一个存在于父 Customers 表中的 CustomerID 值。如果 CustomerID 存在于 Customers 表之外的 Orders 表中,则 ForeignKeyConstraint 将引发异常。

如果子列可能包含父列不包含的值,添加 DataRelation 时请将 createConstraints 标志设置为 false。在该示例中,对于 Orders 表和 OrderDetails 表之间的 DataRelation,createConstraints 标志将设置为 false。这样,应用程序就可以返回 OrderDetails 表中的所有记录并只返回 Orders 表中记录的子集,而不会生成运行时异常。

-----------------------------------------------------------------------------------------------------------------------------------------------------

【ms-help://MS.MSDNQTR.v90.chs/fxref_system.data/html/adcdd95a-5faa-ed66-c9fa-5bf972bfe233.htm】

DataRelation 类

表示两个 DataTable 对象之间的父/子关系。

命名空间:  System.Data
程序集:  System.Data(在 System.Data.dll 中)

“折叠”图像 语法

Visual Basic(声明)
Public
 Class
 DataRelation
Visual Basic(用法)
Dim
 instance
 As
 DataRelation
C#
public
 class
 DataRelation
Visual C++
public
 ref class
 DataRelation
J#
public
 class
 DataRelation
JScript
public
 class
 DataRelation

“折叠”图像 备注

使用 DataRelation 通过 DataColumn 对象将两个 DataTable 对象相互关联。例如在“客户/订单”关系中,客户表是关系的父表,订单表是子表。此关系类似于主键/外键关系。有关更多信息,请参见 导航 DataRelation (ADO.NET)。

关系是在父表和子表中的匹配的列之间创建的。即,两个列的 DataType 值必须相同。

关系还可以将父级 DataRow 中的各种更改层叠到其子行。若要控制在子行中如何更改值,请将 ForeignKeyConstraint 添加到 DataTable 对象的 ConstraintCollectionConstraintCollection 确定在删除或更新父表中的值时采取什么操作。

在创建 DataRelation 时,它首先验证是否可以建立关系。在将它添加到 DataRelationCollection 之后,通过禁止会使关系无效的任何更改来维持此关系。在创建 DataRelation 和将其添加到 DataRelationCollection 之间的这段时间,可以对父行或子行进行其他更改。如果这样会使关系不再有效,则会生成异常。

DataRelation 对象包含在 DataRelationCollection 中,后者可以通过 DataSetRelations 属性、DataTableChildRelationsParentRelations 属性来访问。

“折叠”图像 示例

下面的示例创建一个新的 DataRelation 并将其添加到 DataSetDataRelationCollection 中。

Visual Basic  “复制”图像 复制代码
Private
 Sub
 CreateRelation()
    ' Get the DataColumn objects from two DataTable objects 

    ' in a DataSet. Code to get the DataSet not shown here.

    Dim
 parentColumn As
 DataColumn = _
        DataSet1.Tables("Customers").Columns("CustID"
)
    Dim
 childColumn As
 DataColumn = DataSet1.Tables( _
        "Orders").Columns("CustID"
)

    ' Create DataRelation.

    Dim
 relCustOrder As
 DataRelation
    relCustOrder = New
 DataRelation( _
        "CustomersOrders"
, parentColumn, childColumn)

    ' Add the relation to the DataSet.

    DataSet1.Relations.Add(relCustOrder)
End
 Sub


C#  “复制”图像 复制代码
private
 void
 CreateRelation() 
{
// Get the DataColumn objects from two DataTable objects
// in a DataSet. Code to get the DataSet not shown here.
DataColumn parentColumn =
DataSet1.Tables["Customers"].Columns["CustID" ];
DataColumn childColumn =
DataSet1.Tables["Orders"].Columns["CustID" ];
// Create DataRelation.
DataRelation relCustOrder;
relCustOrder = new DataRelation("CustomersOrders" ,
parentColumn, childColumn);
// Add the relation to the DataSet.
DataSet1.Relations.Add(relCustOrder);
}

“折叠”图像 继承层次结构

System. . :: . Object
  System.Data. . :: . DataRelation

“折叠”图像 线程安全

该类型对于多线程读操作是安全的。您必须使任何写操作同步。

posted on 2010-01-28 16:58  GT_Andy  阅读(922)  评论(0编辑  收藏  举报