我一直在搜索Select和SelectMany之间的区别,但我还没有找到合适的答案。我需要学习使用LINQ to SQL时的差异,但我所找到的都是标准数组示例。
有人能提供一个LINQ到SQL的例子吗?
我一直在搜索Select和SelectMany之间的区别,但我还没有找到合适的答案。我需要学习使用LINQ to SQL时的差异,但我所找到的都是标准数组示例。
有人能提供一个LINQ到SQL的例子吗?
当前回答
只是为了另一种观点,可能会帮助一些函数式程序员:
选择是映射 SelectMany是绑定的(或flatMap的Scala/Kotlin人)
其他回答
下面是一个用于测试的初始化小集合的代码示例:
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; }
}
没有太多的技术-数据库与许多组织,每个有许多用户:-
var orgId = "123456789";
var userList1 = db.Organizations
.Where(a => a.OrganizationId == orgId)
.SelectMany(a => a.Users)
.ToList();
var userList2 = db.Users
.Where(a => a.OrganizationId == orgId)
.ToList();
都为所选组织返回相同的ApplicationUser列表。
第一个“项目”从Organization到Users,第二个直接查询Users表。
SelectMany有几个重载。其中之一允许您在遍历层次结构时跟踪父节点和子节点之间的任何关系。
示例:假设您有以下结构:League -> Teams -> Player。
您可以很容易地返回一个平坦的播放器集合。但是你可能会失去任何关于玩家所在团队的信息。
幸运的是,有一个重载用于此目的:
var teamsAndTheirLeagues =
from helper in leagues.SelectMany
( l => l.Teams
, ( league, team ) => new { league, team } )
where helper.team.Players.Count > 2
&& helper.league.Teams.Count < 10
select new
{ LeagueID = helper.league.ID
, Team = helper.team
};
前面的例子来自Dan的IK博客。我强烈建议你看一看。
SelectMany扁平查询,返回列表的列表。例如
public class PhoneNumber
{
public string Number { get; set; }
}
public class Person
{
public IEnumerable<PhoneNumber> PhoneNumbers { get; set; }
public string Name { get; set; }
}
IEnumerable<Person> people = new List<Person>();
// Select gets a list of lists of phone numbers
IEnumerable<IEnumerable<PhoneNumber>> phoneLists = people.Select(p => p.PhoneNumbers);
// SelectMany flattens it to just a list of phone numbers.
IEnumerable<PhoneNumber> phoneNumbers = people.SelectMany(p => p.PhoneNumbers);
// And to include data from the parent in the result:
// pass an expression to the second parameter (resultSelector) in the overload:
var directory = people
.SelectMany(p => p.PhoneNumbers,
(parent, child) => new { parent.Name, child.Number });
Live Demo。net Fiddle
SelectMany()允许您以一种需要第二个Select()或循环的方式折叠多维序列。
更多细节请参见这篇博客文章。