.NET(C#) LINQ 简介

Linq是Language Integrated Query的简称,它是微软在.NET Framework 3.5里面新加入的特性,用以简化查询查询操作。主要包含:Linq to Object、Linq to SQL、Linq to XML,其中Linq to Object和对于对象的查询,Linq to XML则又提供了对XML格式数据的检索、设置等方法,本文主要介绍.NET(C#) 中Linq简介。

1、Linq to Object

“LINQ to Objects”指直接将 LINQ 查询与任何 IEnumerableIEnumerable<T> 集合一起使用,而不使用中间 LINQ 提供程序或 API, 可以使用 LINQ 来查询任何可枚举的集合,例如 List<T>ArrayDictionary<TKey,TValue>。 该集合可以是用户定义的集合,也可以是由 .NET API 返回的集合。

“LINQ to Objects”表示一种新的处理集合的方法。 采用旧方法,必须编写指定如何从集合检索数据的复杂的 foreach 循环。 而采用 LINQ 方法,只需编写描述要检索的内容的声明性代码。

LINQ 查询与传统 foreach 循环相比具有三大优势:

1)它们更简明、更易读,尤其在筛选多个条件时。

2)它们使用最少的应用程序代码提供强大的筛选、排序和分组功能。

3)无需修改或只需做很小的修改即可将它们移植到其他数据源。

通常,对数据执行的操作越复杂,就越能体会到 LINQ 相较于传统迭代技术的优势。

例如,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication7LINQ
{
    class Customer
    {
        public string ID { get; set; }
        public string City { get; set; }
        public string Country { get; set; }
        public string Region { get; set; }
        public decimal Sales { get; set; }
        public override string ToString()//重写ToString(),默认的ToString()仅输出类型名称        {
            return "ID:" + ID + "City:" + City + "Country:" + Country + "Region:" + Region + "Sales:" + Sales;
        }
    }
    class Order
    {
        public string ID { get; set; }
        public decimal Amount { get; set; }
    }
    class Program
    {
        /// <summary>
        /// 生成随机数组
        /// </summary>
        /// <param name="count"></param>
        /// <returns></returns>
        private static int[] GenerateLotsofNumbers(int count)
        {
            Random generator = new Random(1); //使用指定的种子值初始化 Random 类的新实例。
            int[] result = new int[count];
            for (int i = 0; i < count; i++)
            {
                result[i] = generator.Next();
            }
            return result;
        }
        //1.用var关键字声明结果变量
        //2.指定数据源:from 子句
        //3.指定条件:where 子句
        //4.指定元素:select子句
        //5.完成:使用foreach循环
        static void Main(string[] args)
        {
           // string[] names = { "Alono", "Zheng", "Yuan", "Song", "Simle", "Hsieh", "Small", "She", "Sza", "Sam", "Fa", "Iyl" };
           // //var queryResults = from n in names
           // //                   where n.StartsWith("S")
           // //                   orderby n descending//按照最后一个字母排序 ordeby n.Substring(n.Length - 1)
           // //                   select n;//查询语法
           // var queryResults = names.OrderBy(n => n).Where(n => n.StartsWith("S"));//方法语法 Lambda 表达式
           //// var queryResults = names.OrderByDescending(n => n).Where(n => n.StartsWith("S"));
           // foreach (var item in queryResults)
           //     Console.WriteLine(item);
           // Console.ReadKey();
           //--------------------------------------------------------------------------------------------------
            //int[] numbers = GenerateLotsofNumbers(12345678);
            //var queryResults = from n in numbers
            //                   where n < 1000
            //                   select n;
            //foreach (var item in queryResults)
            //{
            //    Console.WriteLine(item);
            //}
            //Console.WriteLine("聚合运算符......");
            //Console.WriteLine(queryResults.Count());
            //Console.WriteLine(queryResults .Max ());
            //Console.WriteLine(queryResults.Average());
            //Console.WriteLine(queryResults.Sum());
            //Console.ReadKey();
            //--------------------------------------------------------------------------------------------------
            List<Customer> customers = new List<Customer> {
                new Customer {ID ="A",City ="New York",Country ="USA",Region ="North America",Sales =9999},
                new Customer {ID ="B",City ="New York",Country ="USA",Region ="North America",Sales =9999},
                 new Customer {ID ="C",City ="XiAn",Country ="China",Region ="Asia",Sales =7777},
                  new Customer {ID ="D",City ="New York",Country ="USA",Region ="North America",Sales =9999},
                   new Customer {ID ="E",City ="BeiJing",Country ="China",Region ="Asia",Sales =8888},
                    new Customer {ID ="F",City ="New York",Country ="USA",Region ="North America",Sales =9999}
            };
            //var queryReaults =
            //    from n in customers
            //    where n.Region == "Asia"
            //    select n;
            //foreach (var item in queryReaults )
            //    Console.WriteLine(item);
            //Console.ReadKey();
            //--------------------------------------投影----------------------------------------------
            //投影是在LINQ查询中从其他数据类型中创建新数据类型的术语。
            //var queryResults =
            //    from c in customers
            //    where c.Region == "Asia"
            //    select new { c.City, c.Country, c.Sales };
            //var queryResults = customers.Where(c => c.Region == "Asia").Select(c => new { c.City, c.Country, c.Sales });
            //var queryResults = customers.Select(c => new { c.City, c.Country, c.Sales }).Where(c => c.City == "XiAn");
            //foreach (var item in queryResults)
            //    Console.WriteLine(item);
            //Console.ReadKey();
            //--------------------单值选择查询------------------------
            var queryResults1 = customers.Select(c => c.Region).Distinct();
            var queryResults2 = (from c in customers select c.Region).Distinct();
            //------------------------Any和All---------------------------------
            bool anyUSA = customers.Any(c => c.Country == "USA");
            if(anyUSA )
                Console.WriteLine("some customers are in USA");
            else
                Console.WriteLine("WAWA");
            bool allAsia = customers.All(c => c.Region == "Asia");
            if(allAsia )
                Console.WriteLine("WAWA");
            else
                Console.WriteLine("All customers are in Asia");
           // Console.ReadKey();
            //--------------------------------多级排序---------------------------------------
            var queryReaults3 =
                from n in customers
                where n.Region == "Asia"
                orderby n.Region ,n.Country descending ,n.City //查询语法 多级排序
                select n;
            var queryResults4 =
                customers.OrderBy(c => c.Region).ThenByDescending(c => c.Country).ThenBy(c => c.City).Select(c => new { c.ID, c.Region, c.Country, c.City });
                //方法语法 多级排序
            //------------------------------------组合查询(group query)-------------------------------------
            //组合查询中的数据通过一个键(Key)字段来组合,每一个组中的所有成员都共享这个字段值,在这个例子中 键字段是Region 
            //要计算每个组的总和,应先生成一个新的结果集cg
            var queryResults5 = from c in customers
                                group c by c.Region into cg
                                select new { TotalSales = cg.Sum(c => c.Sales), Region = cg.Key };
            var orderedResults = from cg in queryResults5
                                 orderby cg.TotalSales descending
                                 select cg;
            foreach (var item in orderedResults)
                Console.WriteLine(item.TotalSales + "\t:" + item.Region);
            //Console.ReadKey();
            //------------------------Take 和 Skip----------------------------------
            //Take() 从查询结果中提取前n个结果
            //Skip() 从查询结果中跳过前n个结果 返回剩余的结果
            foreach (var item in orderedResults .Take (2))
                Console.WriteLine(item.TotalSales + "\t:" + item.Region);
            //---------------------------First 和 FirstOrDefault-------------------------------
            //First() 返回结果集中第一个匹配给定条件的元素
            //FirstOrDefault() 当查询条件不满足是,将为列表返回默认元素 而使用First()则返回null
            Console.WriteLine(queryReaults3.FirstOrDefault(n => n.Region == "Asia"));
            //--------------------------------集运算符-----------------------------
            List<Order> orders = new List<Order>{
            new Order {ID="A",Amount=100},
            new Order {ID ="B",Amount =200},
            new Order {ID ="H",Amount =300}};
            var customersIDs = from c in customers
                               select c.ID;
            var ordersIDs = from o in orders
                            select o.ID;
            var customersWithOrders = customersIDs.Intersect(ordersIDs);//Intersect()
            foreach (var item in customersWithOrders )
                Console.WriteLine(item );
            Console.WriteLine("-------------------------");
            var ordersNoCustomers = ordersIDs.Except(customersIDs);//Except()
            foreach (var item in ordersNoCustomers )
                Console.WriteLine(item );
            Console.WriteLine("-------------------------");
            var allCustomersOrders = ordersIDs.Union(customersIDs);//Union()
            foreach (var item in allCustomersOrders)
                Console.WriteLine(item);
            //Console.ReadKey();
            //---------------------------------Join----------------------------
            //使用Join运算符在一个查询中查找多个集合中的相关数据,用键字段把结果连接起来
            var queryResults9 =
                from c in customers
                join o in orders on c.ID equals o.ID
                select new { c.ID, c.City, SalesBefore = c.Sales, NewOrder = o.Amount, SalesAfter = c.Sales + o.Amount };
            foreach (var item in queryResults9 )
                Console.WriteLine(item );
            Console.ReadKey();
        }
    }
}

2、Linq to SQL

LINQ to SQL 是 .NET Framework 3.5版的一个组件,提供用于将关系数据作为对象管理的运行时基础结构。

在 LINQ to SQL 中,关系数据库的数据模型映射到用开发人员所用的编程语言表示的对象模型。 当应用程序运行时,LINQ to SQL 会将对象模型中的语言集成查询转换为 SQL,然后将它们发送到数据库进行执行。当数据库返回结果时,LINQ to SQL 会将它们转换回使用的编程语言处理的对象。

例如,

DataClasses1DataContext datacontext = new DataClasses1DataContext(); 
var singleStudent = from s in datacontext.studentInfo 
                    where s.studentName != "zhang3" 
                    orderby s.classInfo descending 
                    select s; 
IList<studentInfo> studentList = singleStudent.Skip(pageSize * (pageNumber - 1)).Take(pageSize).ToList(); 
foreach (studentInfo student in studentList) 
{ 
    Console.WriteLine("studentId:" + student.studentId + "studentName:" + student.studentName); 
} 

3、Linq to XML

LINQ to XML 是 .NET Framework 3.5 版中用于处理 XML 数据的新模型。 LINQ to XML 允许开发人员对 XML 数据执行任何需要的操作:查询、修改、创建、保存,和序列化 XML 文档。 真正的优势在于查询和创建功能。

LINQ to XML 中的查询简洁而易于表示,与 XPath 或 XQuery 相比,使用的语法更类似于 SQL。 由于查询结果可作为为元素或属性的集合而返回,并且可用作 XElement 对象的参数,因此可以容易地将 XML 树从一种形状转换为另一种形状。

LINQ to XML 利用 .NET Framework 3.5 版中的语言集成查询 (LINQ) 技术。 LINQ 扩展了 C# 和 Visual Basic 的语言语法,提供可以扩展到几乎任何数据存储区的强大的查询功能。

1)创建XML

XElement contacts = 
    new XElement("Students", 
    new XElement("Student", 
        new XElement("Name", "Xiao Ming"), 
        new XElement("Phone", "99599", 
        new XAttribute("Type", "Home")), 
        new XElement("phone", "010-99599", 
        new XAttribute("Type", "Work")), 
        new XElement("Address", 
            new XElement("Street", "123 Street"), 
            new XElement("City", "123 City"), 
            new XElement("State", "1"), 
            new XElement("Postal", "0000000") 
        ) 
    ) 
); 
contacts.Save("test.xml");

XML内容如下:

<?xml version="1.0" encoding="utf-8"?> 
<Students> 
  <Student> 
    <Name>Xiao Ming</Name> 
    <Phone Type="Home">99599</Phone> 
    <phone Type="Work">010-99599</phone> 
    <Address> 
      <Street>123 Street</Street> 
      <City>123 City</City> 
      <State>1</State> 
      <Postal>0000000</Postal> 
    </Address> 
  </Student> 
</Students> 

2)查询XML

XElement root = XElement.Load("test.xml"); 
IEnumerable address = from el in root.Elements("Student").Elements("phone") 
                      where el.Attribute("Type").Value == "Work" 
                      select el; 
foreach (XElement el in address) 
{ 
    Console.WriteLine(el.Value); 
}
推荐阅读
cjavapy编程之路首页