나는 사이의 차이를 검색했습니다 Select
및 SelectMany
하지만 적절한 답을 찾을 수 없어. LINQ To SQL을 사용할 때의 차이점을 알아야하지만 내가 찾은 것은 표준 배열 예입니다.
누군가 LINQ To SQL 예제를 제공 할 수 있습니까?
나는 사이의 차이를 검색했습니다 Select
및 SelectMany
하지만 적절한 답을 찾을 수 없어. LINQ To SQL을 사용할 때의 차이점을 알아야하지만 내가 찾은 것은 표준 배열 예입니다.
누군가 LINQ To SQL 예제를 제공 할 수 있습니까?
답변:
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 });
많은 제품이 교차 제품을 취하는 SQL의 교차 조인 작업 과 유사 합니다.
예를 들어
Set A={a,b,c}
Set B={x,y}
많은 세트를 사용하여 다음 세트를 얻을 수 있습니다
{ (x,a) , (x,b) , (x,c) , (y,a) , (y,b) , (y,c) }
여기서 우리는 세트 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 });
믹스는 평평한 구조에서 다음과 같은 요소를 갖습니다.
{(10,cat), (10,dog), (10,donkey), (20,cat), (20,dog), (20,donkey)}
SelectMany
입니다 . 오히려 이것은 SelectMany
사용할 수 있는 방법 이지만 실제로는 일반적인 방법은 아닙니다.
Where
후 SelectMany 조건을
SelectMany()
다른 방법으로 초 Select()
또는 루프가 필요한 방식으로 다차원 시퀀스를 축소 할 수 있습니다 .
이 블로그 게시물에 대한 자세한 내용 .
에 여러 가지 과부하가 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
조인 바로 가기처럼 작동한다고 이해 합니다.
그래서 당신은 할 수 있습니다 :
var orders = customers
.Where(c => c.CustomerName == "Acme")
.SelectMany(c => c.Orders);
.SelectMany(c => new {c.CompanyName, c.Orders.ShippedDate});
작동하지 않습니다. SelectMany는 목록 목록을 편평하게 만들고 결과에 포함 된 목록 중 하나만 선택할 수 있습니다. 비교 : Linq의 내부 조인 .
일부 SelectMany가 필요하지 않을 수 있습니다. 2 개 미만의 쿼리는 동일한 결과를 제공합니다.
Customers.Where(c=>c.Name=="Tom").SelectMany(c=>c.Orders)
Orders.Where(o=>o.Customer.Name=="Tom")
일대 다 관계의 경우
from o in Orders
join c in Customers on o.CustomerID equals c.ID
where c.Name == "Tom"
select o
너무 많은 기술을 습득하지 않고 많은 조직이있는 데이터베이스, 각 사용자가 많은 경우 :-
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 테이블을 직접 쿼리합니다.
이 예제를 고려하십시오.
var array = new string[2]
{
"I like what I like",
"I like what you like"
};
//query1 returns two elements sth like this:
//fisrt element would be array[5] :[0] = "I" "like" "what" "I" "like"
//second element would be array[5] :[1] = "I" "like" "what" "you" "like"
IEnumerable<string[]> query1 = array.Select(s => s.Split(' ')).Distinct();
//query2 return back flat result sth like this :
// "I" "like" "what" "you"
IEnumerable<string> query2 = array.SelectMany(s => s.Split(' ')).Distinct();
"SelectMany"가 여러 시퀀스에 걸쳐 평평 해지고 투영되므로 "I"또는 "like"와 같은 중복 값이 query2에서 제거되었습니다. 그러나 query1은 일련의 문자열 배열을 반환합니다. query1 (두 번째 요소 및 두 번째 요소)에 두 개의 다른 배열이 있으므로 제거 할 항목이 없습니다.
하위 배열 객체 데이터를 축적하기 위해 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();
usersArray.SelectMany(ua => ua.Phones.Select(p => p.BasePart))
다음은 테스트를 위해 초기화 된 작은 컬렉션이있는 코드 예제입니다.
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 query =
Enumerable
.Range(1, 10)
.SelectMany(ints => Enumerable.Range(1, 10), (a, b) => $"{a} * {b} = {a * b}")
.ToArray();
Console.WriteLine(string.Join(Environment.NewLine, query));
Console.Read();
곱셈표 예.