博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

使用LINQ访问数据集

Posted on 2010-12-07 19:57  itcfj  阅读(471)  评论(0编辑  收藏  举报

 使用LINQ访问数据集

王然

微软认证讲师

wangran@itgoldenbridge.com

 

 

点击添加MSN机器人小新

为您收听下载MSDN中文网络广播课程加油助力!

 

 

本次课程内容包括

? LINQ to DataSet 概述

- 数据集

- LINQ to DataSet

? LINQ to DataSet 查询

- 启用 LINQ to DataSet 功能 - 使用标准查询操作符 - 基于方法的查询 - 查询交叉表

- 查询类型化数据集

 

 

议程

? LINQ to DataSet 概述

- 数据集

- LINQ to DataSet

? LINQ to DataSet 查询

- 启用 LINQ to DataSet 功能 - 使用标准查询操作符 - 基于方法的查询 - 查询交叉表

- 查询类型化数据集

 

 

数据集(DataSet)

? DataSet 是更为广泛使用的 ADO.NET 组件

       之一,它可以显式缓存不同数据源中的数 据。

? 在表示层上 , DataSet 与 GUI 控件紧密集

       成,以进行数据绑定。

? 在中间层上,它提供保留数据关系形状的 缓存并包括快速简单查询和层次结构导航 服务,从而可以减少对数据库的请求数。

 

 

查询数据集

? DataSet 虽然具有突出的优点,但其查询功

       能也存在限制。

? Select 方法可用于筛选和排序,

       GetChildRows 和 GetParentRow 方法可用 于层次结构导航。

? 但对于更复杂的情况,开发人员必须编写

       自定义查询。 这会使应用程序性能低下并 且难以维护。

 

 

使用LINQ to DataSet

?  使用 LINQ toDataSet 可以更快更容易地查询在

       DataSet 对象中缓存的数据。

?  这些查询用编程语言本身表示,而不表示为嵌入

       在应用程序代码中的字符串。

?  LINQ to DataSet 可使 Visual Studio 开发人员的

       工作效率更高,因为Visual Studio IDE 提供编译 时语法检查、静态类型化和对 LINQ 的智能感知 的支持。

?  LINQ to DataSet 也可用于查询从一个或多个数据

       源合并的数据。  这可以使许多需要灵活表示和处 理数据的方案能够实现。

 

 

使用原有ADO.NET代码

? 现有的 ADO.NET 2.0 代

       码将继续在 LINQto

       DataSet 应用程序中有效。 ? 右图阐释了 LINQ to

       DataSet 与 ADO.NET2.0 和数据存储区的关系。

 

 

查询数据集

? 填充 DataSet

- XxxDataAdapter -LINQ to SQL

? 主要使用下面两个扩展类

-DataRowExtensions

-DataTableExtensions

? 查询支持

- 类型化数据集 - 非类型化数据集

 

 

构建N层应用程序

? 在 N 层应用程序中,DataSet 通常用于中

       间层以缓存 Web 应用程序的信息。 ? LINQ to DataSet 查询功能通过扩展方法实

       现 ,并扩展现有的 ADO.NET 2.0 DataSet。

 

 

议程

? LINQ to DataSet 概述

- 数据集

- LINQ to DataSet

? LINQ to DataSet 查询

- 启用 LINQ to DataSet 功能 - 使用标准查询操作符 - 基于方法的查询 - 查询交叉表

- 查询类型化数据集

 

 

启用 LINQ to DataSet 功能

? 要求 .NET Framework 3.5

? 引用 System.Data.DataSetExtensions 程

       序集

 

 

使用标准查询运算符

? 可以使用下面LINQ标准查询运算符

- from

- where

       select

 

 

基于方法的查询语法

? 表述 LINQ to DataSet 查询的另一种方法 ? 是对 LINQ 运算符方法的一系列直接方法调

       用

? 需要将 Lambda 表达式作为参数进行传递

 

 

延迟查询

? 当查询旨在返回一系列值时,查询变量本

       身只存储查询命令。

? 如果查询不包含可使查询立即执行的方法,

       则查询的实际执行将会推迟 ,直到在 foreach 或 For Each 循环中循环访问查询 变量。

? 延迟执行可使多个查询组合在一起或使查

       询得到扩展。

 

 

主动查询

? 使用下列方法可以进行主动查询:

-ToList<TSource>

-ToArray<TSource>

       ToLookup

- ToDictionary

 

 

交叉表查询

? LINQ 提供两个联接运算符

- Join:对于关系数据库,Join 实现内部联接。 - GroupJoin:对于关系数据库,GroupJoin运算

       符没有直接等效项 ,它们实现内部联接和左外 部联接的超集。

? 这些运算符执行同等联接,即仅在键相等

       时匹配两个数据源的联接。

 

 

查询类型化数据集

? 对于类型化 DataSet,不必使用泛型Field

       方法或SetField 方法即可访问列数据。 ? 由于 DataSet 中包括类型信息,因此属性

       名称在编译时可用。

? LINQ to DataSet 提供对正确类型的列值的

       访问,以便可以在编译代码时而不是在运 行时捕获类型不匹配错误。

 

 

比较 DataRow

? LINQ 定义多种用于比较源元素的集合运算

       符以查看它们是否相等:

- Distinct:返回序列中的非重复元素

       Union : 生成两个序列的并集 - Intersect:生成两个序列的交集- Except:生成两个序列的差集

? 这些运算符通过对每个元素集合调用

       GetHashCode 和 Equals 方法来比较源元 素。

 

 

通过查询创建数据表

?  CopyToDataTable 方法

?  它使用下面的过程通过查询创建DataTable

- CopyToDataTable 方法克隆源表中的 DataTable - 克隆的DataTable 的架构从源表中枚举的第一个

       DataRow 对象的列生成,克隆表的名称是源表的名称 后面追加单词“query”。

- 对于源表中的每一行,会将行内容复制到新 DataRow

       对象中,然后将该对象插入到克隆表中。

- 复制完可查询的输入表中的所有 DataRow 对象后,将

       返回克隆的DataTable。如果源序列不包含任何 DataRow 对象 ,则该方法将返回一个空 DataTable。

 

 

数据绑定和 LINQ to DataSet

? LINQ to DataSet 通过提供基于表达式的

       LINQ 筛选和排序,扩展了DataView 筛选 和排序的功能,它允许执行比基于字符吕 睥筛选和排序更为复杂且功能更为强大的 筛选和排序操作。

 

 

 

using System;

usingSystem.Collections.Generic;

using System.Linq;

using System.Text;

using System.Data;

usingSystem.Data.SqlClient;

usingSystem.Globalization;

 

namespaceLINQtoDataSet

{

    class Program

    {

        /// <summary>

        /// 填充数据集

        /// </summary>

        /// <param name="ds">数据集</param>

        static void FillDataSet(DataSet ds)

        {

            try

            {

                // Create a new adapter andgive it a query to fetch sales order, contact,

                // address, and productinformation for sales in the year 2002. Point connection

                // information to theconfiguration setting "AdventureWorks".

                string connectionString ="Data Source=localhost;Initial Catalog=AdventureWorks;"

                    + "Integrated Security=true;";

 

 

                SqlDataAdapter da = newSqlDataAdapter(

                    "SELECT SalesOrderID,ContactID, OrderDate, OnlineOrderFlag, " +

                    "TotalDue,SalesOrderNumber, Status, ShipToAddressID, BillToAddressID " +

                    "FROMSales.SalesOrderHeader " +

                    "WHERE DATEPART(YEAR,OrderDate) = @year; " +

 

                    "SELECTd.SalesOrderID, d.SalesOrderDetailID, d.OrderQty, " +

                    "d.ProductID, d.UnitPrice" +

                    "FROMSales.SalesOrderDetail d " +

                    "INNER JOINSales.SalesOrderHeader h " +

                    "ON d.SalesOrderID =h.SalesOrderID  " +

                    "WHERE DATEPART(YEAR,OrderDate) = @year; " +

 

                    "SELECT p.ProductID,p.Name, p.ProductNumber, p.MakeFlag, " +

                    "p.Color, p.ListPrice,p.Size, p.Class, p.Style, p.Weight " +

                    "FROMProduction.Product p; " +

 

                    "SELECT DISTINCT a.AddressID,a.AddressLine1, a.AddressLine2, " +

                    "a.City,a.StateProvinceID, a.PostalCode " +

                    "FROM Person.Address a" +

                    "INNER JOINSales.SalesOrderHeader h " +

                    "ON  a.AddressID = h.ShipToAddressID ORa.AddressID = h.BillToAddressID " +

                    "WHERE DATEPART(YEAR,OrderDate) = @year; " +

 

                    "SELECT DISTINCTc.ContactID, c.Title, c.FirstName, " +

                    "c.LastName,c.EmailAddress, c.Phone " +

                    "FROM Person.Contact c" +

                    "INNER JOINSales.SalesOrderHeader h " +

                    "ON c.ContactID =h.ContactID " +

                    "WHERE DATEPART(YEAR,OrderDate) = @year;",

                connectionString);

 

                // Add table mappings.

               da.SelectCommand.Parameters.AddWithValue("@year", 2002);

               da.TableMappings.Add("Table", "SalesOrderHeader");

               da.TableMappings.Add("Table1", "SalesOrderDetail");

               da.TableMappings.Add("Table2", "Product");

               da.TableMappings.Add("Table3", "Address");

               da.TableMappings.Add("Table4", "Contact");

 

                // Fill the DataSet.

                da.Fill(ds);

 

                // Add data relations.

                DataTable orderHeader =ds.Tables["SalesOrderHeader"];

                DataTable orderDetail =ds.Tables["SalesOrderDetail"];

                DataRelation order = newDataRelation("SalesOrderHeaderDetail",

                                        orderHeader.Columns["SalesOrderID"],

                                        orderDetail.Columns["SalesOrderID"], true);

                ds.Relations.Add(order);

 

                DataTable contact =ds.Tables["Contact"];

                DataTable orderHeader2 =ds.Tables["SalesOrderHeader"];

                DataRelation orderContact = newDataRelation("SalesOrderContact",

                                               contact.Columns["ContactID"],

                                                orderHeader2.Columns["ContactID"],true);

                ds.Relations.Add(orderContact);

            }

            catch (SqlException ex)

            {

                Console.WriteLine("SQLexception occurred: " + ex.Message);

            }

        }

 

        static void Main(string[]args)

        {

            //Method1();

            //Method2();

            //Method3();

            //Method4();

            //Method5();

            //Method6();

            //Method7();

            //Method8();

            //Method9();

        }

 

        [STAThread()]

        private static void Method9()

        {

            BindingForm form = newBindingForm();

            form.ShowDialog();

        }

 

        /// <summary>

        /// 通过查询创建数据表

        /// </summary>

        private static void Method8()

        {

            DataSet ds = new DataSet();

            ds.Locale =CultureInfo.InvariantCulture;

            FillDataSet(ds);

 

            DataTable orders =ds.Tables["SalesOrderHeader"];

 

            // Query the SalesOrderHeader tablefor orders placed

            // after August 8, 2001.

            IEnumerable<DataRow> query =

                from order inorders.AsEnumerable()

                where order.Field<DateTime>("OrderDate")> new DateTime(2001, 8, 1)

                select order;

 

            // Create a table from the query.

            DataTable boundTable =query.CopyToDataTable<DataRow>();

 

            foreach (DataRow row inboundTable.Rows)

            {

               Console.WriteLine("{0}\t{1}", row["SalesOrderID"],row["OrderDate"]);

            }

        }

 

        /// <summary>

        /// 比较DataRow

        /// </summary>

        private static void Method7()

        {

            // Fill the DataSet.

            DataSet ds = new DataSet();

            ds.Locale =CultureInfo.InvariantCulture;

            FillDataSet(ds);

 

            DataTable contactTable =ds.Tables["Contact"];

 

            // Create two tables.

            IEnumerable<DataRow> query1 =from contact in contactTable.AsEnumerable()

                                          wherecontact.Field<string>("Title") == "Ms."

                                         select contact;

 

            IEnumerable<DataRow> query2 =from contact in contactTable.AsEnumerable()

                                          wherecontact.Field<string>("FirstName") == "Sandra"

                                         select contact;

 

            DataTable contacts1 =query1.CopyToDataTable();

            DataTable contacts2 =query2.CopyToDataTable();

 

            // Find the intersection of the twotables.

            var contacts =contacts1.AsEnumerable().Intersect(contacts2.AsEnumerable(),

                                                               DataRowComparer.Default);

 

           Console.WriteLine("Intersection of contacts tables");

            foreach (DataRow row in contacts)

            {

                Console.WriteLine("Id: {0}{1} {2} {3}",

                    row["ContactID"],row["Title"], row["FirstName"], row["LastName"]);

            }

        }

 

        /// <summary>

        /// 查询类型化数据集

        /// </summary>

        private static void Method6()

        {

            AW.ProductDataTable products = newAW.ProductDataTable();

            AWTableAdapters.ProductTableAdapteradapter = new LINQtoDataSet.AWTableAdapters.ProductTableAdapter();

            adapter.Fill(products);

 

            var query = from p in products

                        wherep.FinishedGoodsFlag == true

                        select new

                        {

                            p.ProductID,

                            p.Name,

                            p.ProductNumber

                        };

 

            foreach (var product in query)

            {

               Console.WriteLine("{0}\t{1:d}\t{2}",

                    product.ProductID,

                    product.Name,

                    product.ProductNumber);

            }

        }

 

        /// <summary>

        /// 交叉表查询

        /// </summary>

        private static void Method5()

        {

            // Fill the DataSet.

            DataSet ds = new DataSet();

            ds.Locale =CultureInfo.InvariantCulture;

            FillDataSet(ds);

 

            DataTable orders =ds.Tables["SalesOrderHeader"];

            DataTable details =ds.Tables["SalesOrderDetail"];

 

            var query =

                from order inorders.AsEnumerable()

                join detail indetails.AsEnumerable()

                onorder.Field<int>("SalesOrderID") equals

                   detail.Field<int>("SalesOrderID")

                where order.Field<bool>("OnlineOrderFlag")== true

                &&order.Field<DateTime>("OrderDate").Month == 8

                select new

                {

                    SalesOrderID =

                       order.Field<int>("SalesOrderID"),

                    SalesOrderDetailID =

                       detail.Field<int>("SalesOrderDetailID"),

                    OrderDate =

                       order.Field<DateTime>("OrderDate"),

                    ProductID =

                       detail.Field<int>("ProductID")

                };

 

 

            foreach (var order in query)

            {

               Console.WriteLine("{0}\t{1}\t{2:d}\t{3}",

                    order.SalesOrderID,

                    order.SalesOrderDetailID,

                    order.OrderDate,

                    order.ProductID);

            }

        }

 

        /// <summary>

        /// 强制查询

        /// </summary>

        private static void Method4()

        {

            // Fill the DataSet.

            DataSet ds = new DataSet();

            ds.Locale =CultureInfo.InvariantCulture;

            FillDataSet(ds);

 

            DataTable products =ds.Tables["Product"];

 

            IEnumerable<DataRow> query =

                from product inproducts.AsEnumerable()

                orderbyproduct.Field<Decimal>("ListPrice") descending

                select product;

 

            // Force immediate execution of thequery.

            IEnumerable<DataRow>productsArray = query.ToArray();

 

            Console.WriteLine("Every pricefrom highest to lowest:");

            foreach (DataRow prod inproductsArray)

            {

                Console.WriteLine(prod.Field<Decimal>("ListPrice"));

            }

 

        }

 

        /// <summary>

        /// 延迟查询

        /// </summary>

        private static void Method3()

        {

            // Fill the DataSet.

            DataSet ds = new DataSet();

            ds.Locale =CultureInfo.InvariantCulture;

            FillDataSet(ds);

 

            DataTable products =ds.Tables["Product"];

 

            IEnumerable<DataRow>productsQuery =

                from product inproducts.AsEnumerable()

                select product;

 

            IEnumerable<DataRow>largeProducts =

                productsQuery.Where(p =>p.Field<string>("Size") == "L");

 

            Console.WriteLine("Products ofsize 'L':");

            foreach (DataRow product inlargeProducts)

            {

               Console.WriteLine(product.Field<string>("Name"));

            }

        }

 

        /// <summary>

        /// 使用基于方法的查询语法

        /// </summary>

        private static void Method2()

        {

            DataSet ds = new DataSet();

            ds.Locale =CultureInfo.InvariantCulture;

            FillDataSet(ds);

 

            DataTable products =ds.Tables["Product"];

 

            var query =products.AsEnumerable().

                Select(product => new

                {

                    ProductName =product.Field<string>("Name"),

                    ProductNumber =product.Field<string>("ProductNumber"),

                    Price =product.Field<decimal>("ListPrice")

                });

 

            Console.WriteLine("ProductInfo:");

            foreach (var productInfo in query)

            {

                Console.WriteLine("Productname: {0} Product number: {1} List price: ${2} ",

                    productInfo.ProductName,productInfo.ProductNumber, productInfo.Price);

            }

 

 

        }

 

        /// <summary>

        /// 使用标准查询操作符

        /// </summary>

        private static void Method1()

        {

            // Fill the DataSet.

            DataSet ds = new DataSet();

            ds.Locale =CultureInfo.InvariantCulture;

            FillDataSet(ds);

 

            DataTable products =ds.Tables["Product"];

 

            IEnumerable<DataRow> query =

                from product inproducts.AsEnumerable()

                select product;

 

            Console.WriteLine("ProductNames:");

            foreach (DataRow p in query)

            {

               Console.WriteLine(p.Field<string>("Name"));

            }

 

        }

    }

}