痛而后能善
无惧于闯
Make a greate impact

[翻译]Pro C# 2008 and the .NET 3.5 Platform, Fourth Edition 第二十四章 LINQ API编程(一)

本章翻译目的为学习之用,英文版权属原作者所有,中文版权根据turingbook的贴子归图灵,如有侵权,请告知删除,禁止用于商业用途!在此特别鸣谢图灵的傅老师(本章翻译的贴出征得她的同意)和杨福川(为大家介绍了这本好书)。本人翻译水平有限,错误之处难免望大家批评指正!

  

第24章 LINQ API编程

 

       既然前面已经用了两章来介绍ADO.NET编程模型,我们现在返回语言集成查询的地位中去。本章开始研究LINQ to ADO.NET的作用。该特殊术语用于描述LINQ编程模型的相关方面,特别是LINQ to DataSet和LINQ to SQL。正如你所期望的那样,这些API允许你使用LINQ查询关系型数据库和ADO.NET数据集对象。

    本章余下部分将研究LINQ to XML的作用。这一方面LINQ不仅仅能用预期的查询操作符集合从XML文档中提取数据,而且可通过一种极其直接的方式来装载,保存,和生成XML文档(比起System.Xml.dll集合中的类型包)。

 

注意:本章假设你已经掌握在第14章中提到的LINQ编程模型。

 

24.1 LINQ to ADO.NET作用

 

    正如在14章中解释的那样,LINQ是一种允许程序员创建能应用于多种数据存储(例如,数组,集合,数据库,XML文档等)的强类型查询表达式编程模型。尽管你常常使用相同的查询操作符而不必考虑LINQ查询的目标对象,LINQ to ADO.NET API提供额外的类和底层框架来集成LINQ和数据库。

 

    如前面提到的那样,LINQ to ADO.NET是LINQ中描述两个以数据库为核心的新术语。这一API本质上是标准ADO.NET 数据集编程模型的扩展,该模型使得DataSets,DataTables,和DataRows自然地成为LINQ查询表达式的目标对象。除了用System.Core.dll的类型,LINQ to DataSet要求项目中使用System.Data.DataSetExtensions.dll集中的辅助类。

   

     LINQ to ADO.NET的第二个部件是LINQ to SQL。该API允许你和关系数据库进行交互,通过使用实体类抽象底层ADO.NET数据类型(如链接,命令,数据适配器等)。通过使用这些实体类,可用直观的对象模型来表示关系型数据和用LINQ查询操作数据。LINQ to SQL功能性包含在System.Data.Linq.dll集合中。 

 

注意: 在.NET 3.5中,LINQ to SQL并不支持数据供给生产模型(详见第二十二章)。因此,在使用API中,你的数据必须贮存在Microsoft SQL服务器中。然而,LINQ to DataSet API是与数据库无关的,所以可操作任何关系型数据库中的数据集。

 

24.2 LINQ to DataSet编程

 

        回顾之前的章节,数据集类型是断开层的核心,它被用作表示内部相关的DataTable对象的缓存备份和他们之间(有选择)的关系。在相关的注意事项中,你也许回忆起DataSet中的数据可以通过三种不同方式来操作:

索引器

数据表读取器

强类型数据员

 

在运用多个数据集和数据表的索引器的时候,可以通过一种相当直接但却是弱类型方式来和数据交互。回顾这些方法需要你把数据当作由多个单元格组成的扁平模块。例如:

 

    static void PrintDataWithIndxers(DataTable dt)

    {

        // 打印数据表

        for (int curRow = 0; curRow < dt.Rows.Count; curRow++)

        {

            for (int curCol = 0; curCol < dt.Columns.Count; curCol++)

            {

                Console.Write(dt.Rows[curRow][curCol].ToString() + ""t");

            }

            Console.WriteLine();

        }

}

 

DataTable类型的CreateDataReader()方法提供了第二种方式,这样就可以把DataSet中的数据当作线性行集合并通过连续的方式来进行处理。

 

    static void PrintDataWithDataTableReader(DataTable dt)

    {

        // 获取 DataTableReader 类型.

        DataTableReader dtReader = dt.CreateDataReader();

        while (dtReader.Read())

        {

            for (int i = 0; i < dtReader.FieldCount; i++)

            {

                Console.Write("{0}"t", dtReader.GetValue(i));

            }

            Console.WriteLine();

        }

        dtReader.Close();

    }

 

最终,用强类型集合DataSet生成一个代码基,它允许你使用属性的方式和对象中的数据交互,该属性和关系型数据库中的实际列名匹配。

 

回顾第23章中,我们运用强类型对象来写代码,如下所示:

    static void AddRowWithTypedDataSet()

    {

        InventoryTableAdapter invDA = new InventoryTableAdapter();

        AutoLotDataSet.InventoryDataTable inv = invDA.GetData();

        inv.AddInventoryRow(999, "Ford", "Yellow", "Sal");

        invDA.Update(inv);

    }

 

当所有这些方法都有其用处,LINQ to DataSet提供了别的选择,用LINQ表达式操作当中的数据。除此之外,ADO.NET DataSet(和相关类型比如DataTable和DataView)不具有必要的底层框架作为LINQ查询的直接对象。例如,下面的方法就会导致编译错误:

 

    static void LinqOverDataTable()

    {

        // 获取 a DataTable 数据

        InventoryDALDisLayer dal = new InventoryDALDisLayer(

        @"Data Source=(local)"SQLEXPRESS;" +

        "Initial Catalog=AutoLot;Integrated Security=True");

        DataTable data = dal.GetAllInventory();

        // 获取 CarID > 5的Car记录

        var moreData = from c in data where (int)c["CarID"] > 5 select c;

    }

 

如果在过去你曾编译类似LinqOverDataTable()的方法,编译器就会通知你,DataTable类型并没有提供一个“查询模式实现”。与处理LINQ没有实现IEnumerable<T>接口(比如ArrayList)的对象过程类似,ADO.NET对象必须转换成兼容类型。为了理解它是如何实现的,让我们来研究System.Data.DataSetExtensions.dll类型。

posted on 2008-08-25 09:50  greater  阅读(2065)  评论(4编辑  收藏  举报