ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Linq SelectMany

2022-07-18 19:32:49  阅读:171  来源: 互联网

标签:Purchases Customers Description Price Linq var Name SelectMany


Linq SelectMany

SelectMany

SelectMany查询语法

from 标识符1  in 可枚举的表达式1
from 标识符2  in 可枚举的表达式2

先看一个简单的例子

string[] arr = { "a b c", "x y z", "1 2 3" };
            var q1 = from a in arr
                from b in a.Split()
                select b;
// 方法语法
var q1 = arr.SelectMany(a => a.Split());
  
foreach (var item in q1)
            {
                Console.WriteLine(item);
            }
// a-b-c-x-y-z-1-2-3-

将嵌套的结构展平化

image-20220718185104508

假如使用arr.Select(a => a.Split());,会发现得到的是层次化的结果

image-20220718181945195
var q2 = from a in arr
            from b in a.Split()
            orderby a, b
            select b + " come from " + a;
image-20220718182559583

转换成方法语法

       var q2 = arr.SelectMany(a => a.Split(), (a, b) => new { a, b })
                .OrderBy(@t => @t.a)
                .ThenBy(@t => @t.b)
                .Select(@t => @t.b + " come from " + @t.a);

SelectMany CROSS JOIN

var q1 = from c in context.Customers
                from p in context.Purchases
                select c.Name +" buy "+ p.Price;
                
//SELECT (COALESCE([c].[Name], N'') + N' buy ') + CAST([p].[Price] AS nvarchar(max))
FROM [Customers] AS [c]
CROSS JOIN [Purchases] AS [p]
WHERE [c].[Id] = [p].[CustomerId]

SelectMany INNER JOIN

如果采用导航属性

 var q1 = from c in context.Customers
                from p in c.Purchases
                select c.Name +" buy "+ p.Price;
                
// SELECT (COALESCE([c].[Name], N'') + N' buy ') + CAST([p].[Price] AS nvarchar(max))
FROM [Customers] AS [c]
INNER JOIN [Purchases] AS [p] ON [c].[Id] = [p].[CustomerId]

SelectMany LEFT JOIN

使用DefaultIfEmpty

var q1 = 
				from c in context.Customers
                from p in c.Purchases.DefaultIfEmpty()
                select new { c.Name, p.Description, Price = (decimal?)p.Price };
                
// SELECT [c].[Name], [p].[Description], CAST([p].[Price] AS decimal(18,2)) AS [Price]
FROM [Customers] AS [c]
LEFT JOIN [Purchases] AS [p] ON [c].[Id] = [p].[CustomerId]

上面的写法在本地查询的时候可能会报错,当p为null时,p.Description p.Price会产生空指针错误。需要改写兼容两种场景

  var q1 =
                from c in context.Customers
                from p in c.Purchases.DefaultIfEmpty()
                select new
                {
                    c.Name,
                    Description = p == null ? "" : p.Description,
                    Price = p == null ? (double?)null : p.Price
                };
                
// SELECT [c].[Name], CASE
    WHEN [p].[Id] IS NULL THEN N''
    ELSE [p].[Description]
END AS [Description], CAST([p].[Price] AS decimal(18,2)) AS [Price]
FROM [Customers] AS [c]
LEFT JOIN [Purchases] AS [p] ON [c].[Id] = [p].[CustomerId]

现在添加 Price>60 筛选

   var q1 =
                from c in context.Customers
                from p in c.Purchases.DefaultIfEmpty()
                where p.Price > 60
                select new
                {
                    c.Name,
                    Description = p == null ? "" : p.Description,
                    Price = p == null ? (double?)null : p.Price
                };
                
// SELECT [c].[Name], CASE
    WHEN [p].[Id] IS NULL THEN N''
    ELSE [p].[Description]
END AS [Description], [p].[Price]
FROM [Customers] AS [c]
LEFT JOIN [Purchases] AS [p] ON [c].[Id] = [p].[CustomerId]
WHERE [p].[Price] > 60.0E0
image-20220718191446724

发现where是在left join之后,正确的写法应该是

 var q1 =
                from c in context.Customers
                from p in c.Purchases.Where(p => p.Price > 60).DefaultIfEmpty()
                select new
                {
                    c.Name,
                    Description = p == null ? "" : p.Description,
                    Price = p == null ? (double?)null : p.Price
                };
                
// SELECT [c].[Name], CASE
    WHEN [t].[Id] IS NULL THEN N''
    ELSE [t].[Description]
END AS [Description], [t].[Price]
FROM [Customers] AS [c]
LEFT JOIN (
    SELECT [p].[Id], [p].[CustomerId], [p].[Description], [p].[Price]
    FROM [Purchases] AS [p]
    WHERE [p].[Price] > 60.0E0
) AS [t] ON [c].[Id] = [t].[CustomerId]
image-20220718191825281

Select子查询产生的是层次化的结构,不需要进行额外的null值处理。

标签:Purchases,Customers,Description,Price,Linq,var,Name,SelectMany
来源: https://www.cnblogs.com/toyz9/p/16491717.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有