841

LINQ에서 GroupBy 다중 열을 수행하려면 어떻게해야합니까?

SQL에서 이와 비슷한 :

SELECT * FROM <TableName> GROUP BY <Column1>,<Column2>

어떻게 이것을 LINQ로 변환 할 수 있습니까?

QuantityBreakdown
(
    MaterialID int,
    ProductID int,
    Quantity float
)

INSERT INTO @QuantityBreakdown (MaterialID, ProductID, Quantity)
SELECT MaterialID, ProductID, SUM(Quantity)
FROM @Transactions
GROUP BY MaterialID, ProductID

12 답변


1083

익명 유형을 사용하십시오.

예 :

group x by new { x.Column1, x.Column2 }


  • 익명 유형을 사용하여 그룹화를 처음 사용하는 경우 ' 새 ' 이 예제의 키워드는 마술을 수행합니다. - Chris
  • nHibernate가 dll 문제에 대해 오류가 발생하는 mvc의 경우. GroupBy (x = > new {x.Column1, x.Column2}, (key, group) = > new {Key1 = key.Column1, Key2 = key.Column2, Result = group.ToList ); - Milan
  • 나는이 경우에 새로운 물체가 참조에 의해 비교 될 것이라고 생각 했으므로 일치하지 않았다. 그루핑이 없었다. - HoGo
  • @HoGo 익명 형식화 된 객체그들 자신의 Equals와 GetHashCode를 구현한다.객체를 그룹화 할 때 사용되는 메소드. - Byron Carasco
  • Linq를 처음 사용하면 출력 데이터 구조를 시각화하기가 다소 힘듭니다. 익명 형식이 키로 사용되는 그룹화가 생성됩니까? - Jacques

661

절차 샘플

.GroupBy(x => new { x.Column1, x.Column2 })


  • 반환되는 개체 유형은 무엇입니까? - mggSoft
  • @MGG_Soft는 익명 형식입니다. - Alex
  • 구문이 약간 떨어져서 잘못된 익명 형식 선언자가 나타납니다. .GroupBy (x = > new {Column1 = x.Column1, Column2 = x.Column2}) - Tom Maher
  • @ 톰이 방법대로 작동해야합니다. 익명 형식의 필드 이름 지정을 건너 뛸 때 C #은 프로젝션에서 마지막으로 액세스 한 속성 / 필드의 이름을 사용한다고 가정합니다. (귀하의 예는 Mo0gles와 동일합니다.) - Crisfole
  • 내 대답을 찾았 어. Column1 및 Column2 속성을 포함하는 새로운 엔티티 (MyViewEntity)를 정의해야하며 반환 유형은 다음과 같습니다. IEnumerable < IGrouping < MyViewEntity, MyEntity > > 및 그룹 코드 스 니핑은 다음과 같습니다. MyEntityList.GroupBy (myEntity = > new MyViewEntity {Column1 = myEntity.Column1, Column2 = myEntity.Column2}); - Amir Chatrbahr

431

좋아, 이것을 얻었다 :

var query = (from t in Transactions
             group t by new {t.MaterialID, t.ProductID}
             into grp
                    select new
                    {
                        grp.Key.MaterialID,
                        grp.Key.ProductID,
                        Quantity = grp.Sum(t => t.Quantity)
                    }).ToList();


  • +1 - 포괄적 인 예제에 감사드립니다. 다른 답변의 스 니펫은 너무 짧고 문맥이 없습니다. 또한 집계 함수를 표시합니다 (이 경우 Sum). 매우 도움이됩니다. 공통적 인 시나리오로 그룹화 된 집계 함수 (즉, MAX, MIN, SUM 등)를 나란히 사용합니다. - barrypicker
  • 여기에 :stackoverflow.com/questions/14189537/…그룹화가 이름이 알려진 단일 열을 기반으로하는 경우 데이터 표가 표시되지만 그룹화를 기반으로하는 열을 동적으로 생성해야하는 경우 어떻게 할 수 있습니까? - b.g
  • 이는 그룹화 개념을 이해하고 그 위에 집계를 적용하는 데 실제로 도움이됩니다. - rajibdotnet
  • 위대한 예를 들어 보겠습니다. 나는 골반을 필요로하기 때문에 이것이 나의 요구를 해결하기에 충분할만큼 람다를 찾고 있었지만 이것이 완벽한 해답이었다. - Kevbo

128

여러 열로 그룹화하려면 다음을 시도하십시오 ...

GroupBy(x=> new { x.Column1, x.Column2 }, (key, group) => new 
{ 
  Key1 = key.Column1,
  Key2 = key.Column2,
  Result = group.ToList() 
});

같은 방법으로 Column3, Column4 등을 추가 할 수 있습니다.


  • 그것은 매우 도움이되었고 더 많은 upvotes를 얻어야합니다!Result모든 열에 연결된 모든 데이터 세트를 포함합니다. 고마워요! - j00hi
  • note : ToList () 대신 .AsEnumerable ()을 사용해야했습니다. - GMan
  • 굉장, 고마워. 여기에 나와있는 예가 있습니다. GetFees는 IQueryable < Fee >를 반환합니다. (AccountAd = key.AccountId, FeeName = key.FeeName, KeyAuthority, KeyAuthorityId) AppliedFee = group.Sum (x = > x.AppliedFee) ?? 0M}). ToList (); - Craig B
  • 그룹화되지 않은 다른 쿼리를이 쿼리에서 가져올 수 있습니까? 개체 배열이 있으면이 개체를 두 개의 열로 그룹화하고 싶습니다. 그러나 두 개의 열뿐만 아니라 개체의 모든 속성을 가져옵니다. - FrenkyB

18

C #7부터 값 튜플을 사용할 수도 있습니다.

group x by (x.Column1, x.Column2)

또는

.GroupBy(x => (x.Column1, x.Column2))



16

강력한 형식의 그룹화에 Tuple < >을 사용할 수도 있습니다.

from grouping in list.GroupBy(x => new Tuple<string,string,string>(x.Person.LastName,x.Person.FirstName,x.Person.MiddleName))
select new SummaryItem
{
    LastName = grouping.Key.Item1,
    FirstName = grouping.Key.Item2,
    MiddleName = grouping.Key.Item3,
    DayCount = grouping.Count(), 
    AmountBilled = grouping.Sum(x => x.Rate),
}


  • 참고 : Linq To Entities에서는 새 튜플 만들기가 지원되지 않습니다. - foolmoron

8

이 질문은 클래스 속성별로 그룹에 대해 묻지 만 DataTable과 같은 ADO 개체에 대해 여러 열을 기준으로 그룹화하려면 변수에 "새"항목을 할당해야합니다.

EnumerableRowCollection<DataRow> ClientProfiles = CurrentProfiles.AsEnumerable()
                        .Where(x => CheckProfileTypes.Contains(x.Field<object>(ProfileTypeField).ToString()));
// do other stuff, then check for dups...
                    var Dups = ClientProfiles.AsParallel()
                        .GroupBy(x => new { InterfaceID = x.Field<object>(InterfaceField).ToString(), ProfileType = x.Field<object>(ProfileTypeField).ToString() })
                        .Where(z => z.Count() > 1)
                        .Select(z => z);


  • 새 {c.Field String ( "Title"), c.Field < String > ( "CIF")} "로 Linq 쿼리 " 그룹 c를 수행 할 수 없습니다. 많은 시간!! 최종 질의는 다음과 같다 : "그룹 c by new {titulo = c.Field < String > ("title "), cif = c.Field < String > - netadictos

5

var Results= query.GroupBy(f => new { /* add members here */  });


  • 이전 답변에 아무 것도 추가하지 않습니다. - Mike Fuchs

2

.GroupBy(x => x.Column1 + " " + x.Column2)


  • 함께Linq.Enumerable.Aggregate()동적 인 속성 수를 기준으로 그룹화 할 수도 있습니다.propertyValues.Aggregate((current, next) => current + " " + next). - Kai Hartmann
  • 이것은 누구나 믿을만한 답보다 나은 대답입니다. "column"이 column1이 다른 상황 ( "ab" "cde"가 "abc" "de"와 일치 함)에 대해 동일한 것으로 같을 경우의 조합의 인스턴스가있을 수있는 경우 문제가 될 수 있습니다. 즉, 별도의 표현식을 사용하여 그룹 뒤에 람다를 사전 구성하기 때문에 동적 유형을 사용할 수없는 경우이 방법이 훌륭한 솔루션입니다. - Brandon Barkley
  • "ab" "cde" 실제로 " abc "와 일치하지 않아야합니다. "de", 따라서 그 사이에 공백이있다. - Kai Hartmann

2

x를 new {x.Col, x.Col}로 묶는다.


2

.GroupBy(x => (x.MaterialID, x.ProductID))


  • 이 코드가 문제를 해결하는 방법에 대한 설명을 추가하는 것을 고려하십시오. - Rosário Pereira Fernandes
  • 이것은 질문에 대한 대답을 제공하지 않습니다. 비평하거나 저자의 설명을 요청하려면 게시물 아래에 의견을 남겨 둡니다. -리뷰에서 - Mamun

0

주의해야 할 것은 람다 식의 객체를 보내야하고 클래스에 인스턴스를 사용할 수 없다는 것입니다.

예:

public class Key
{
    public string Prop1 { get; set; }

    public string Prop2 { get; set; }
}

이것은 컴파일되지만 생성 할 것이다.1 사이클 당 하나의 키.

var groupedCycles = cycles.GroupBy(x => new Key
{ 
  Prop1 = x.Column1, 
  Prop2 = x.Column2 
})

핵심 속성의 이름을 지정하지 않은 채로 다시 가져올 수 없으면 대신 이렇게 할 수 있습니다. 이것은GroupBy올바르게 입력하고 핵심 속성을 제공하십시오.

var groupedCycles = cycles.GroupBy(x => new 
{ 
  Prop1 = x.Column1, 
  Prop2= x.Column2 
})

foreach (var groupedCycle in groupedCycles)
{
    var key = new Key();
    key.Prop1 = groupedCycle.Key.Prop1;
    key.Prop2 = groupedCycle.Key.Prop2;
}

연결된 질문


관련된 질문

최근 질문