我一直在搜索Select和SelectMany之间的区别,但我还没有找到合适的答案。我需要学习使用LINQ to SQL时的差异,但我所找到的都是标准数组示例。
有人能提供一个LINQ到SQL的例子吗?
我一直在搜索Select和SelectMany之间的区别,但我还没有找到合适的答案。我需要学习使用LINQ to SQL时的差异,但我所找到的都是标准数组示例。
有人能提供一个LINQ到SQL的例子吗?
当前回答
SelectMany()的正式描述是:
将序列的每个元素投射到IEnumerable上并展开 产生的序列变成一个序列。
SelectMany()将结果序列平铺成一个序列,并对其中的每个元素调用结果选择器函数。
class PetOwner
{
public string Name { get; set; }
public List<String> Pets { get; set; }
}
public static void SelectManyEx()
{
PetOwner[] petOwners =
{ new PetOwner { Name="Higa, Sidney",
Pets = new List<string>{ "Scruffy", "Sam" } },
new PetOwner { Name="Ashkenazi, Ronen",
Pets = new List<string>{ "Walker", "Sugar" } },
new PetOwner { Name="Price, Vernette",
Pets = new List<string>{ "Scratches", "Diesel" } } };
// Query using SelectMany().
IEnumerable<string> query1 = petOwners.SelectMany(petOwner => petOwner.Pets);
Console.WriteLine("Using SelectMany():");
// Only one foreach loop is required to iterate
// through the results since it is a
// one-dimensional collection.
foreach (string pet in query1)
{
Console.WriteLine(pet);
}
// This code shows how to use Select()
// instead of SelectMany().
IEnumerable<List<String>> query2 =
petOwners.Select(petOwner => petOwner.Pets);
Console.WriteLine("\nUsing Select():");
// Notice that two foreach loops are required to
// iterate through the results
// because the query returns a collection of arrays.
foreach (List<String> petList in query2)
{
foreach (string pet in petList)
{
Console.WriteLine(pet);
}
Console.WriteLine();
}
}
/*
This code produces the following output:
Using SelectMany():
Scruffy
Sam
Walker
Sugar
Scratches
Diesel
Using Select():
Scruffy
Sam
Walker
Sugar
Scratches
Diesel
*/
主要的区别是每个方法的结果,而SelectMany()返回一个扁平的结果;Select()返回一个列表的列表,而不是一个扁平的结果集。
因此,SelectMany的结果是一个列表
{斯库菲,山姆,沃克,甜甜,划痕,迪塞尔}
你可以迭代每一项。但是对于select的结果,您需要一个额外的foreach循环来遍历结果,因为查询返回一个数组集合。
其他回答
我理解SelectMany工作起来像一个连接快捷方式。
所以你可以:
var orders = customers
.Where(c => c.CustomerName == "Acme")
.SelectMany(c => c.Orders);
SelectMany()允许您以一种需要第二个Select()或循环的方式折叠多维序列。
更多细节请参见这篇博客文章。
下面是一个用于测试的初始化小集合的代码示例:
class Program
{
static void Main(string[] args)
{
List<Order> orders = new List<Order>
{
new Order
{
OrderID = "orderID1",
OrderLines = new List<OrderLine>
{
new OrderLine
{
ProductSKU = "SKU1",
Quantity = 1
},
new OrderLine
{
ProductSKU = "SKU2",
Quantity = 2
},
new OrderLine
{
ProductSKU = "SKU3",
Quantity = 3
}
}
},
new Order
{
OrderID = "orderID2",
OrderLines = new List<OrderLine>
{
new OrderLine
{
ProductSKU = "SKU4",
Quantity = 4
},
new OrderLine
{
ProductSKU = "SKU5",
Quantity = 5
}
}
}
};
//required result is the list of all SKUs in orders
List<string> allSKUs = new List<string>();
//With Select case 2 foreach loops are required
var flattenedOrdersLinesSelectCase = orders.Select(o => o.OrderLines);
foreach (var flattenedOrderLine in flattenedOrdersLinesSelectCase)
{
foreach (OrderLine orderLine in flattenedOrderLine)
{
allSKUs.Add(orderLine.ProductSKU);
}
}
//With SelectMany case only one foreach loop is required
allSKUs = new List<string>();
var flattenedOrdersLinesSelectManyCase = orders.SelectMany(o => o.OrderLines);
foreach (var flattenedOrderLine in flattenedOrdersLinesSelectManyCase)
{
allSKUs.Add(flattenedOrderLine.ProductSKU);
}
//If the required result is flattened list which has OrderID, ProductSKU and Quantity,
//SelectMany with selector is very helpful to get the required result
//and allows avoiding own For loops what according to my experience do code faster when
// hundreds of thousands of data rows must be operated
List<OrderLineForReport> ordersLinesForReport = (List<OrderLineForReport>)orders.SelectMany(o => o.OrderLines,
(o, ol) => new OrderLineForReport
{
OrderID = o.OrderID,
ProductSKU = ol.ProductSKU,
Quantity = ol.Quantity
}).ToList();
}
}
class Order
{
public string OrderID { get; set; }
public List<OrderLine> OrderLines { get; set; }
}
class OrderLine
{
public string ProductSKU { get; set; }
public int Quantity { get; set; }
}
class OrderLineForReport
{
public string OrderID { get; set; }
public string ProductSKU { get; set; }
public int Quantity { get; set; }
}
再举一个如何使用SelectMany + Select来累积子数组对象数据的例子。
假设我们有一些带着手机的用户:
class Phone {
public string BasePart = "555-xxx-xxx";
}
class User {
public string Name = "Xxxxx";
public List<Phone> Phones;
}
现在我们需要选择所有用户的所有手机的basepart:
var usersArray = new List<User>(); // array of arrays
List<string> allBaseParts = usersArray.SelectMany(ua => ua.Phones).Select(p => p.BasePart).ToList();
当查询返回一个字符串(一个char数组)时更清楚:
例如,如果列表" Fruits "包含" apple "
'Select'返回字符串:
Fruits.Select(s=>s)
[0]: "apple"
'SelectMany'将字符串平展:
Fruits.SelectMany(s=>s)
[0]: 97 'a'
[1]: 112 'p'
[2]: 112 'p'
[3]: 108 'l'
[4]: 101 'e'