四、联接操作符

联接是指将一个数据源对象与另一个数据源对象进行关联或者联合的操作。这两个数据源对象通过一个共同的值或者属性进行关联。

LINQ有两个联接操作符: Join GroupJoin

1. Join

Join 操作符类似于T-SQL中的 inner join ,它将两个数据源相联接,根据两个数据源中相等的值进行匹配。例如,可以将产品表与产品类别表相联接,得到产品名称和与其相对应的类别名称。以下的代码演示了这一点:

//查询语法
var query =
    (from p in db.Products
     join c in db.Categories on p.CategoryID equals c.CategoryID
     where p.CategoryID == 1
     select new { p.ProductID, p.ProductName, c.CategoryID, c.CategoryName }).ToList();

生成的sql:

SELECT 
    [Extent1].[ProductID] AS [ProductID], 
    [Extent1].[ProductName] AS [ProductName], 
    [Extent2].[CategoryID] AS [CategoryID], 
    [Extent2].[CategoryName] AS [CategoryName]
    FROM  [dbo].[Products] AS [Extent1]
    INNER JOIN [dbo].[Categories] AS [Extent2] ON [Extent1].[CategoryID] = [Extent2].[CategoryID]
    WHERE (1 = [Extent1].[CategoryID]) AND ([Extent1].[CategoryID] IS NOT NULL)
//方法语法
var q =
    db.Products
    .Join
        db.Categories,
        p => p.CategoryID,
        c => c.CategoryID,
        (p, c) => new { p.ProductID, p.ProductName, c.CategoryID, c.CategoryName }
    .Where(p => p.CategoryID == 1)
    .ToList();

生成的sql:

SELECT 
    [Extent1].[ProductID] AS [ProductID], 
    [Extent1].[ProductName] AS [ProductName], 
    [Extent2].[CategoryID] AS [CategoryID], 
    [Extent2].[CategoryName] AS [CategoryName]
    FROM  [dbo].[Products] AS [Extent1]
    INNER JOIN [dbo].[Categories] AS [Extent2] ON [Extent1].[CategoryID] = [Extent2].[CategoryID]
    WHERE 1 = [Extent2].[CategoryID]

以上代码为表述清晰加入了一个条件“where p.CategoryID == 1”,即仅返回产品类别ID为1的所有产品。

生成的sql语句略有不同。

2. GroupJoin

GroupJoin操作符常应用于返回“主键对象-外键对象集合”形式的查询,例如“产品类别-此类别下的所有产品”。以下的代码演示了这一点:

//查询语法
var query =
    (from c in db.Categories
     join p in db.Products on c.CategoryID equals p.CategoryID into r
     select new
         c.CategoryName,
         Products = r
     }).ToList();
//方法语法
var q =
    db.Categories
    .GroupJoin
       db.Products,
       c => c.CategoryID,
       p => p.CategoryID,
       (c, p) => new
           c.CategoryName,
           Products = p
    .ToList();

生成的sql:

SELECT 
    [Project1].[CategoryID] AS [CategoryID], 
    [Project1].[CategoryName] AS [CategoryName], 
    [Project1].[C1] AS [C1], 
    [Project1].[ProductID] AS [ProductID], 
    [Project1].[ProductName] AS [ProductName], 
    [Project1].[SupplierID] AS [SupplierID], 
    [Project1].[CategoryID1] AS [CategoryID1], 
    [Project1].[QuantityPerUnit] AS [QuantityPerUnit], 
    [Project1].[UnitPrice] AS [UnitPrice], 
    [Project1].[UnitsInStock] AS [UnitsInStock], 
    [Project1].[UnitsOnOrder] AS [UnitsOnOrder], 
    [Project1].[ReorderLevel] AS [ReorderLevel], 
    [Project1].[Discontinued] AS [Discontinued]
    FROM ( SELECT 
        [Extent1].[CategoryID] AS [CategoryID], 
        [Extent1].[CategoryName] AS [CategoryName], 
        [Extent2].[ProductID] AS [ProductID], 
        [Extent2].[ProductName] AS [ProductName], 
        [Extent2].[SupplierID] AS [SupplierID], 
        [Extent2].[CategoryID] AS [CategoryID1], 
        [Extent2].[QuantityPerUnit] AS [QuantityPerUnit], 
        [Extent2].[UnitPrice] AS [UnitPrice], 
        [Extent2].[UnitsInStock] AS [UnitsInStock], 
        [Extent2].[UnitsOnOrder] AS [UnitsOnOrder], 
        [Extent2].[ReorderLevel] AS [ReorderLevel], 
        [Extent2].[Discontinued] AS [Discontinued], 
        CASE WHEN ([Extent2].[ProductID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
        FROM  [dbo].[Categories] AS [Extent1]
        LEFT OUTER JOIN [dbo].[Products] AS [Extent2] ON [Extent1].[CategoryID] = [Extent2].[CategoryID]
    )  AS [Project1]
    ORDER BY [Project1].[CategoryID] ASC, [Project1].[C1] ASC

返回的结果为:
在这里插入图片描述

五、分组操作符

分组是根据一个特定的值将序列中的元素进行分组。LINQ只包含一个分组操作符:GroupBy

下面的示例中使用了产品表,以CategoryID作为分组关键值,按照产品类别对产品进行了分组。

//查询语法
var query =
    (from p in db.Products
     group p by p.CategoryID).ToList();
//方法语法
var q =
    db.Products
    .GroupBy(p => p.CategoryID)
    .ToList();

生成的sql:

SELECT 
    [Project2].[C1] AS [C1], 
    [Project2].[CategoryID] AS [CategoryID], 
    [Project2].[C2] AS [C2], 
    [Project2].[ProductID] AS [ProductID], 
    [Project2].[ProductName] AS [ProductName], 
    [Project2].[SupplierID] AS [SupplierID], 
    [Project2].[CategoryID1] AS [CategoryID1], 
    [Project2].[QuantityPerUnit] AS [QuantityPerUnit], 
    [Project2].[UnitPrice] AS [UnitPrice], 
    [Project2].[UnitsInStock] AS [UnitsInStock], 
    [Project2].[UnitsOnOrder] AS [UnitsOnOrder], 
    [Project2].[ReorderLevel] AS [ReorderLevel], 
    [Project2].[Discontinued] AS [Discontinued]
    FROM ( SELECT 
        [Distinct1].[CategoryID] AS [CategoryID], 
        1 AS [C1], 
        [Extent2].[ProductID] AS [ProductID], 
        [Extent2].[ProductName] AS [ProductName], 
        [Extent2].[SupplierID] AS [SupplierID], 
        [Extent2].[CategoryID] AS [CategoryID1], 
        [Extent2].[QuantityPerUnit] AS [QuantityPerUnit], 
        [Extent2].[UnitPrice] AS [UnitPrice], 
        [Extent2].[UnitsInStock] AS [UnitsInStock], 
        [Extent2].[UnitsOnOrder] AS [UnitsOnOrder], 
        [Extent2].[ReorderLevel] AS [ReorderLevel], 
        [Extent2].[Discontinued] AS [Discontinued], 
        CASE WHEN ([Extent2].[ProductID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C2]
        FROM   (SELECT DISTINCT 
            [Extent1].[CategoryID] AS [CategoryID]
            FROM [dbo].[Products] AS [Extent1] ) AS [Distinct1]
        LEFT OUTER JOIN [dbo].[Products] AS [Extent2] ON ([Distinct1].[CategoryID] = [Extent2].[CategoryID]) OR (([Distinct1].[CategoryID] IS NULL) AND ([Extent2].[CategoryID] IS NULL))
    )  AS [Project2]
    ORDER BY [Project2].[CategoryID] ASC, [Project2].[C2] ASC

在这里插入图片描述
执行GroupBy得到的序列中包含的元素类型为IGrouping<TKey, T>,其Key属性代表了分组时使用的关键值,遍历IGrouping<TKey, T>元素可以读取到每一个T类型。在此示例中,对应的元素类型为IGrouping<int, Products>,其Key属性即为类别ID,遍历它可以读取到每一个产品对象。

六、串联操作符

串联是一个将两个集合联接在一起的过程。在LINQ中,这个过程通过Concat操作符来实现。

在下面的示例中,将会把类别名称串联在产品名称之后:

//方法语法
            var q =
                db.Products
                .Select(p => p.ProductName)
                .Concat
                    db.Categories.Select(c => c.CategoryName)
                .ToList();

生成的sql:

SELECT 
    [UnionAll1].[ProductName] AS [C1]
    FROM  (SELECT 
        [Extent1].[ProductName] AS [ProductName]
        FROM [dbo].[Products] AS [Extent1]
    UNION ALL
        SELECT 
        [Extent2].[CategoryName] AS [CategoryName]
        FROM [dbo].[Categories] AS [Extent2]) AS [UnionAll1]

返回结果77+8=85
在这里插入图片描述

四、联接操作符联接是指将一个数据源对象与另一个数据源对象进行关联或者联合的操作。这两个数据源对象通过一个共同的值或者属性进行关联。LINQ有两个联接操作符:Join和GroupJoin。1. JoinJoin操作符类似于T-SQL中的inner join,它将两个数据源相联接,根据两个数据源中相等的值进行匹配。例如,可以将产品表与产品类别表相联接,得到产品名称和与其相对应的类别名称。以下的代码演示了这一点://查询语法var query = (from p in db.Products /// Linq GroupJoin 類似于 Sql Left outer join private void btnGroupJoin_Click(object sender, EventArgs e) DataSet ds 在进行另一个项目时,我发现自己需要计算各种基础类型的各种数据集的基本统计信息。LINQ有Count,Min,Max和Average,但没有其他统计汇总。像我在这种情况下经常做的那样,我从Google开始,认为其他人一定已经为此写了一些方便的扩展方法。有大量的统计和数值处理程序包,但是我想要的是一种简单且轻便的基本统计数据实现:方差(样本和总体),标准差(样本和总体),协方差,皮尔逊(卡方),范围,中位数,最小二乘,均方根,直方图和众数。
转自:http://www.cnblogs.com/dotnetmvc/p/3680151.html LINQ标准查询操作符(二)——JoinGroupJoinGroupByConcat、 四、联接操作符 联接是指将一个数据源对象与另一个数据源对象进行关联或者联合的操作。这两个数据源对象通过一个共同的值或者属性进行关联。 LINQ有两个联接操作符JoinGroupJoin。 1. Joi...
into 查询条件可能为空 类似于Left Join 第一个Select后面没有接对象。如果接了对象第二个select后就接不上对象。查询出来就是个IGrouping对象,可能与你自己定义的输出对象不一样,然后还要循环取出来在转换。在第二个地方接 就不需要在此转换。 很头大,第一次写这么长的Linq
List<person> pp = new List<person>() { new person() { age=11,isread=true,name="1isi"}, new person() { age=21,isread=true,name="2isi"}, new person() { age=31,isread=true,name="3isi"},
LINQ中的Join对应T-SQL中的内连接,并无左连接的方法,当然也没有右连接。 要达成Left join必须依靠GroupJoin来完成。 GroupJoin顾名思义就是先集团在做加入,加入的不同处在于加入会得到一个一对一的新物件集合(List <T>),而GroupJoin则会得到一对多的物件集合({key,List < T>})。 以下是join与GroupJ...
本文导读:LINQ定义了大约40个查询操作符,如select、from、in、where、group 以及order by,借助于LINQ技术,我们可以使用一种类似SQL的语法来查询任何形式的数据。Linq有很多值得学习的地方,这里我们主要介绍Linq使用Group By。 一、Linq对谁适用 linq的语法通过System.Linq下面的Enumerable类提供支持,通过观察他的签名...
在C#中,你可以使用LINQGroupBy操作符对数据进行分组。下面是一个示例代码,展示如何使用LINQGroupBy操作符在C#中对数据进行分组操作: ```csharp using System; using System.Collections.Generic; using System.Linq; public class Program public static void Main(string[] args) // 示例数据 List<Person> people = new List<Person>() new Person() { Name = "Alice", Age = 25 }, new Person() { Name = "Bob", Age = 30 }, new Person() { Name = "Charlie", Age = 25 }, new Person() { Name = "Dave", Age = 30 } // 使用LINQGroupBy操作符对年龄进行分组 var groupedPeople = people.GroupBy(p => p.Age); // 遍历每个分组,并打印结果 foreach (var group in groupedPeople) Console.WriteLine("Age: " + group.Key); foreach (var person in group) Console.WriteLine("- " + person.Name); Console.WriteLine(); public class Person public string Name { get; set; } public int Age { get; set; } 这个示例中,我们有一个包含姓名和年龄的Person类。我们创建了一个Person对象的列表,并使用LINQGroupBy操作符按照年龄对人员进行分组。 在结果中,每个分组都有一个Key属性,代表该组的年龄。我们遍历每个分组,并打印出该组中的人员姓名。 请注意,为了使用LINQ,你需要在代码中引入System.Linq命名空间。