标签: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-
将嵌套的结构展平化
假如使用arr.Select(a => a.Split());
,会发现得到的是层次化的结果
var q2 = from a in arr
from b in a.Split()
orderby a, b
select b + " come from " + a;
转换成方法语法
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
发现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]
Select子查询产生的是层次化的结构,不需要进行额外的null值处理。
标签:Purchases,Customers,Description,Price,Linq,var,Name,SelectMany 来源: https://www.cnblogs.com/toyz9/p/16491717.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。