Tar*_*rik 993 c# linq linq-to-sql
我一直在寻找和之间的区别Select
,SelectMany
但我找不到合适的答案.我需要了解使用LINQ To SQL时的不同之处,但我发现的只是标准数组示例.
有人可以提供LINQ To SQL示例吗?
Mik*_*Two 1532
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 });
Run Code Online (Sandbox Code Playgroud)
Sri*_*ake 177
选择很多就像SQL中的交叉连接操作一样,它需要交叉产品.
例如,如果我们有
Set A={a,b,c}
Set B={x,y}
Run Code Online (Sandbox Code Playgroud)
选择多个可用于获取以下设置
{ (x,a) , (x,b) , (x,c) , (y,a) , (y,b) , (y,c) }
Run Code Online (Sandbox Code Playgroud)
请注意,这里我们采用可以从集合A和集合B的元素中进行的所有可能组合.
这是您可以尝试的LINQ示例
List<string> animals = new List<string>() { "cat", "dog", "donkey" };
List<int> number = new List<int>() { 10, 20 };
var mix = number.SelectMany(num => animals, (n, a) => new { n, a });
Run Code Online (Sandbox Code Playgroud)
混合物将具有扁平结构的以下元素
{(10,cat), (10,dog), (10,donkey), (20,cat), (20,dog), (20,donkey)}
Run Code Online (Sandbox Code Playgroud)
Ale*_*roR 118
var players = db.SoccerTeams.Where(c => c.Country == "Spain")
.SelectMany(c => c.players);
foreach(var player in players)
{
Console.WriteLine(player.LastName);
}
Run Code Online (Sandbox Code Playgroud)
...
rol*_*and 34
有几个重载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
};
Run Code Online (Sandbox Code Playgroud)
前面的例子来自Dan的IK博客.我强烈建议你看一下.
Nat*_*oop 19
我理解SelectMany像连接快捷方式一样工作.
所以你可以:
var orders = customers
.Where(c => c.CustomerName == "Acme")
.SelectMany(c => c.Orders);
Run Code Online (Sandbox Code Playgroud)
Rez*_*abi 14
所述的SelectMany()方法用于变平的序列,其中每个序列的元素的是一个单独的。
我有类user
相同这样的
class User
{
public string UserName { get; set; }
public List<string> Roles { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
主要的:
var users = new List<User>
{
new User { UserName = "Reza" , Roles = new List<string>{"Superadmin" } },
new User { UserName = "Amin" , Roles = new List<string>{"Guest","Reseption" } },
new User { UserName = "Nima" , Roles = new List<string>{"Nurse","Guest" } },
};
var query = users.SelectMany(user => user.Roles, (user, role) => new { user.UserName, role });
foreach (var obj in query)
{
Console.WriteLine(obj);
}
//output
//{ UserName = Reza, role = Superadmin }
//{ UserName = Amin, role = Guest }
//{ UserName = Amin, role = Reseption }
//{ UserName = Nima, role = Nurse }
//{ UserName = Nima, role = Guest }
Run Code Online (Sandbox Code Playgroud)
您可以对序列的任何项目使用操作
int[][] numbers = {
new[] {1, 2, 3},
new[] {4},
new[] {5, 6 , 6 , 2 , 7, 8},
new[] {12, 14}
};
IEnumerable<int> result = numbers
.SelectMany(array => array.Distinct())
.OrderBy(x => x);
//output
//{ 1, 2 , 2 , 3, 4, 5, 6, 7, 8, 12, 14 }
Run Code Online (Sandbox Code Playgroud)
List<List<int>> numbers = new List<List<int>> {
new List<int> {1, 2, 3},
new List<int> {12},
new List<int> {5, 6, 5, 7},
new List<int> {10, 10, 10, 12}
};
IEnumerable<int> result = numbers
.SelectMany(list => list)
.Distinct()
.OrderBy(x=>x);
//output
// { 1, 2, 3, 5, 6, 7, 10, 12 }
Run Code Online (Sandbox Code Playgroud)
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
*/
Run Code Online (Sandbox Code Playgroud)
主要区别在于每个方法的结果,而 SelectMany() 返回平坦的结果;Select() 返回一个列表的列表,而不是一个平面结果集。
因此 SelectMany 的结果是一个类似的列表
{邋遢、萨姆、沃克、糖、划痕、柴油}
您可以仅通过一个 foreach 迭代每个项目。但是对于 select 的结果,您需要一个额外的 foreach 循环来迭代结果,因为查询返回数组的集合。
某些SelectMany可能没有必要.低于2的查询给出相同的结果.
Customers.Where(c=>c.Name=="Tom").SelectMany(c=>c.Orders)
Orders.Where(o=>o.Customer.Name=="Tom")
Run Code Online (Sandbox Code Playgroud)
对于1对多的关系,
from o in Orders
join c in Customers on o.CustomerID equals c.ID
where c.Name == "Tom"
select o
Run Code Online (Sandbox Code Playgroud)