2011-11-10 6 views
1

사용하여 LINQ GROUPBY 선택에 속성을 설정하려고 :나는 다음과 같은 코드가 루프

public class Report 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public decimal Sales { get; set; } 
} 

var result = myItems.GroupBy(x => new { Id = x.Id, Name = x.Name }).Select(x => new Report { Id = x.Key.Id, Name = x.Key.Name }); 

foreach (var item in result) 
{ 
    item.Sales = anotherColletion.FirstOrDefault(x => x.Id == item.Id).Sales; 
} 

내가 값으로이 방법을 판매 속성을 설정할 수 없습니다 생각합니다. 내가 시도하더라도 :

foreach (var item in result) 
{ 
    item.Sales = 50; 
} 

그러나, 나는 그것이 작동하는 다음 코드를 사용하여 속성을 설정하는 경우 :

var result = myItems.GroupBy(x => new { Id = x.Id, Name = x.Name }).Select(x => new Report { Id = x.Key.Id, Name = x.Key.Name, Sales = 50 }); 

이 디자인에 의해인가를?

답변

5

문제는 LINQ 쿼리가 지연 ("지연된 실행")이라는 것입니다. 은 루프의 각 쿼리 결과에 대한 속성을 설정하는이지만 이러한 결과는 근본적으로 사라집니다. 다시 당신의 foreach (당신이 우리를 표시하지 않은 한), 쿼리가 다시 실행 후 쿼리 의 결과를 열거하고 결과를 다시 때 효과적으로 변경 사항을 취소. 쿼리는 결과 자체가 아니라 결과를 생성하는 방법에 대한 스펙 일뿐입니다.

간단히 수정하면 이 구체화되어 컬렉션에 먼저 쿼리됩니다.

var result = myItems.GroupBy(x => new { Id = x.Id, Name = x.Name }) 
        .Select(x => new Report { Id = x.Key.Id, Name = x.Key.Name }) 
        .ToList(); 

당신의 foreach는 오히려 게으른 쿼리의 결과보다는 메모리 컬렉션의 요소를 돌연변이 끝날 것입니다, 따라서 다운 스트림 볼 수 있습니다. 당신이 그것을 반복 할 때 쿼리가 foreach 루프에서, 그냥

var에 사용중인 결과,

var result = myItems.GroupBy(x => new { Id = x.Id, Name = x.Name }) 
        .Select(x => new Report 
           { 
            Id = x.Key.Id, 
            Name = x.Key.Name, 
            Sales = anotherCollection.First(a => a.Id == x.KeyId) 
                  .Sales 
            }); 
+0

myItems.ToList()를 먼저 수행 한 다음 ToList()를 사용하지 않고 GroupBy()를 수행하면 해당 작업이 계속 실행되거나 계속 쿼리를 다시 실행하게됩니까? – Thomas

+0

@Thomas : 그것은 기술적으로 효과가 있습니다. 왜냐하면 변경 가능한'Report' 객체가 이미 그 단계에서 생성되고 구체화 되었기 때문입니다. 객체 생성이 아닌 그룹화 만 다시 실행됩니다. 나는 그것을하지 않는 것이 좋습니다. – Ani

+0

myItems.ToList()를 구체화하는 이유는 컬렉션에 여러 GroupBy (이 질문에 포함되지 않음)를 사용하고 해당 컬렉션을 계산에 사용하고자하기 때문입니다. 내 추론은 하나의 데이터베이스 쿼리를 실행 한 다음 다른 GroupBy의 메모리 컬렉션을 사용하는 것입니다. 왜 그렇게하는 것을 권하지 않는지 물어봐도 될까요? – Thomas

0

토마스 :

개인적으로

하지만은 쿼리 자체의 속성을 설정하는 것이 좋습니다 , 당신은 새로운 보고서 객체를 생성하고 있지만 그것은 어디에도 '저장'되어 있지 않습니다.

는 문제를 해결하기 위해 쿼리의 끝에 ToArray() 또는 ToList()를 추가

var result = myItems.GroupBy(x => new { Id = x.Id, Name = x.Name }).Select(x => new Report { Id = x.Key.Id, Name = x.Key.Name }).ToList(); 

아미르합니다.

관련 문제