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

Linq

Posted on 2010-11-21 16:43  steve.z  阅读(286)  评论(0)    收藏  举报

语言集成查询 (LINQ) 是 Visual Studio 2008 和 .NET Framework 3.5 中的新功能。

作为 .NET Framework 3.5 的一部分的 LINQ 的组件包括:

  • System.Linq 命名空间,其中包含用于 LINQ 查询的基础结构中的标准查询运算符、类型和接口的集合。此命名空间位于 System.Core.dll 程序集中。

  • System.Data.Linq 命名空间,其中包含支持与 LINQ to SQL 应用程序中的关系数据库进行交互的类。

  • System.Data.Linq.Mapping 命名空间,其中包含可用于生成表示关系数据库的结构和内容的 LINQ to SQL 对象模型的类。

  • System.Xml.Linq 命名空间,其中包含 LINQ to XML 的类。LINQ to XML 是内存中的 XML 编程接口,使您可以轻松有效地修改 XML 文档。通过使用 LINQ to XML,可以加载 XML,序列化 XML,从头创建 XML 树,操作内存中的 XML 树以及使用 XSD 进行验证。还可以组合使用这些功能,将 XML 树从一种形状转换为另一种形状。

  • System.Web.UI.WebControlsSystem.Web.UI.Design.WebControls 命名空间中的新类型。这些新类型(如 LinqDataSource)支持通过数据源控件在 ASP.NET 网页中使用 LINQ。

  • System.Data 命名空间中的 DataRowComparerDataRowExtensionsDataTableExtensions 类支持 LINQ 针对 ADO.NET DataSet 对象的查询。

LINQ主要分为5部分:

  1. LINQ to Objects
  2. LINQ to DataSet
  3. LINQ to SQL
  4. LINQ to XML
  5. LINQ to Entities

关于LINQ的一些注意点:

  •  LINQ的表达式的返回值是一个实现了IEnumerable<T>的迭代器对象,根据LINQ表达式的 不同可能是WhereIterator<T>、SelectIterator、UnionIterator等。所以可声明IEnumerable<T> matches变量来接收LINQ表达式返回值。
  • LINQ表达式的延迟执行,即只有对LINQ表达式返回结果matches进行迭代时(其中包括DataBind()时),才会真正执行表达式。
  • LINQ to Objects用于获取数据的代码比foreach进行的要慢,不过对于ASP.NET网站可以忽略。
  • LINQ表达式可以嵌套使用,可以基于一个LINQ表达式结果再进行LINQ查询。而该LINQ 表达式链仅在最终数据迭代时才进行计算。

1.大量表达式使用示例:
http://msdn.microsoft.com/en-us/vcsharp/aa336746.aspx
2.基本表达式:
from ... in ...
where ...
group ... by ... into g
orderby ...
select...;
3.var--c#中的匿名类型.(只能声明为局部变量,不能做成员变量或参数,因为在编译时不能确定类型。).在不确定Linq表达式返回类型时,可以使用匿名类型。
4.LINQ表达式示例:

List<Employee> l = getEmployees();
        IEnumerable<Employee> matches = from emp in l
                                        where emp.LastName.StartsWith("S")
                                        orderby emp.LastName ascending
                                        select emp;

========================================================

 List<Employee> l = getEmployees();
        IEnumerable<Employee> matches = from emp in l
                                        where emp.LastName.StartsWith("S")
                                        select emp;
        IEnumerable<Employee> m1 = from em in matches
                                   select em;

=========================================================

List<Employee> l = getEmployees();

        //var(匿名类型),只能出现在局部变量声明内,不能作为成员变量或参数。

        ////第一种 var(匿名类型)
        //var matches = from emp in l
        //              select new { FirstName = emp.FirstName, LastName = emp.LastName };

        ////第二种
        //var matches = from emp in l
        //              select emp.FirstName;

        ////第三种
        //var matches = from emp in l
        //              select emp.FirstName + "." + emp.LastName;

        ////第四种 不使用“匿名类”,创建一个单独的简单的实体类EmployeeName(使用构造函数)
        //IEnumerable<EmployeeName> matches = from emp in l
        //                                    select new EmployeeName(emp.FirstName, emp.LastName);

        //第五种,不使用构造函数
        IEnumerable<EmployeeName> matches = from emp in l
                                            select new EmployeeName { FirstName = emp.FirstName, LastName = emp.LastName };

===============================================================================

//在LINQ表达式中调用自定义函数

//所有可以在LINQ表达式中排序的类型必须实现了IComparable接口

 List<Product> l = getProducts();

        //IEnumerable<Product> matches = from p in l
        //                               where p.UnitsInStock > 0 && p.UnitPrice > 3.00M
        //                               select p;
        IEnumerable<Product> matches = from p in l
                                       where MyMethod(p.UnitPrice)
                                       orderby p.UnitPrice descending, p.ProductID ascending
                                       select p;

private bool MyMethod(decimal p)
{

  //该方法最终只需放回true或false
        return true;
}

===============================================================

List<Product> list = getProducts();

        //第一种
        //IEnumerable<IGrouping<int, Product>> matches = from p in list
        //                                               group p by (int)(p.UnitPrice / 50) into g
        //                                               orderby g.Key.ToString()
        //                                               select g;


        ////第二种
        //IEnumerable<int> matches = from p in list
        //                                               group p by (int)(p.UnitPrice / 50) into g
        //                                               orderby g.Key.ToString()
        //                                               select g.Key;

        ////第三种
        //var matches = from p in list
        //                                               group p by (int)(p.UnitPrice / 50) into g
        //                                               orderby g.Key
        //                                               select g;

  //循环分组后的集合
        //遍历所有的组
        foreach (IGrouping<int, Product> item in matches)
        {
            //遍历组中的每条记录
            foreach (Product p in item)
            {
                Response.Write(p.ProductName + "<br/>");
            }
            Response.Write("=============group============<br/>");
        }

        //第四种 调用扩展函数Count()计数。把价格按0~50,50~100,100~150....分组
        var matches = from p in list
                      group p by (int)(p.UnitPrice / 50) into g
                      orderby g.Key.ToString()
                      select new { key = g.Key, 该组中的记录条数 = g.Count() };

 

关于扩展方法,例如:g.Count();g.Max();g.Min();g.Average()等。
在System.Linq.Enumerable静态类中定义了一系列静态方法,所有实现了IEnumerable<T>接口的类的对象都可以调用这些扩展方法。

关于扩展方法使用示例:

 List<Product> list = getProducts();
        var matches = from p in list
                      group p by p.CategoryID into g
                      select new { CategoryId = g.Key, MaxPrice = g.Max(p => p.UnitPrice), MinPrice = g.Min(p => p.UnitPrice), AvgPrice = g.Average(p => p.UnitPrice) };
        gvList.DataSource = matches;
        gvList.DataBind();