2011-10-25 4 views
1

내가 TrackerReport 개체의 다음과 같은 배열을 한 열의 각 값의 합계를 검색 할asp.net C#을 LINQ 쿼리는

public class TrackerMilestone 
{ 
    public int MilestoneId { get; set; } 
    public int CampaignId { get; set; }  
    public string Name { get; set; } 
    public int? SortIndex { get; set; } 
    public string Url { get; set; } 
    public bool IsGoal { get; set; } 
    public bool IsPartialGoal { get; set; } 
    public int? ParentMilestoneId { get; set; } 
    public int? ViewPercent { get; set; } 

    public override string ToString() 
    { 
     return "Id=" + MilestoneId + " | Name=" + Name + " | Url = " + Url; 
    } 
} 

그것은 같이 표시되도록이 더 많거나 적은 :

ID Name Url Counter 
1  A  ab.com  5 
2  N  ac.com  2 

그리고 나는이 워싱턴에 기입이 객체의 목록을 Y :

var trackerReportList = new List<TrackerReport[]>(); 
foreach (var trackerItem in trackerChildren) 
{ 
    //currentReport is the array of TrackerReport TrackerReport[] above mentioned 
    var currentReport = GetReportForItem(GetFromDate(), GetToDate(), trackerItem.ID, 
               FindCampaignId(trackerItem)); 
    trackerReportList.Add(currentReport);  
} 

모든 항목은 동일한 값을 가지고 있지만, 전 대한 카운터, 그래서는 :
목록 1 :

ID Name Url Counter 
1  A  ab.com  5 
2  N  ac.com  2 

리스트 2 :

ID Name Url Counter 
1  A  ab.com  17 
2  N  ac.com  28 

내 목표는이다 카운터 값의 합계를 카운터로하여 단일 TrackerReport []를 생성합니다.

TrackerReport [] :

ID Name Url Counter 
1  A  ab.com  22 
2  N  ac.com  30 

이 작업을 수행하려면 어떤 LINQ 쿼리가 있습니까? 또는 더 나은 솔루션을 찾은 경우 게시하십시오.

미리 감사드립니다.

+0

아버지 클래스를 : D – swapneel

+0

를 잘 추적기가 확실히 사람입니다 : P – Attila

답변

1

귀하의 검색어에 대한 답변은 lambda expression입니다. 당신이 언급 한 경우

TrackerReport[] trackerInfoList = trackerReportList 
    .SelectMany(s => s) 
    .GroupBy(g => g.MilestoneId) 
    .Select(s => 
       { 
        var trackerReportCloned = Clone<TrackerReport[]>(s.First()); 
        trackerReportCloned.Views = s.Sum(su => su.Views); 
        return trackerReportCloned; 
       }) 
    .ToArray(); 

, 나는 그룹화 된 값으로 깊은 복제 한 objectClone<T>(T) 방법을 사용했다. 각 속성을 복사하여 수행 할 수 있었지만 가장 쉬운 것으로 나타났습니다. 계속하기 전에

public static T Clone<T>(T source) 
{ 
    if (!typeof(T).IsSerializable) 
    { 
     throw new ArgumentException("The type must be serializable.", "source"); 
    } 

    // Don't serialize a null object, simply return the default for that object 
    if (Object.ReferenceEquals(source, null)) 
    { 
     return default(T); 
    } 

    IFormatter formatter = new BinaryFormatter(); 
    Stream stream = new MemoryStream(); 
    using (stream) 
    { 
     formatter.Serialize(stream, source); 
     stream.Seek(0, SeekOrigin.Begin); 
     return (T)formatter.Deserialize(stream); 
    } 
} 

, 당신은 설정 [Serializable] 속성을 당신의 DTO 객체에 필요

이것은 Clone() 방법이다.

[Serializable] 
public class TrackerReport : TrackerMilestone 
{ 
    . 
    . 
    . 
} 

[Serializable] 
public class TrackerMilestone 
{ 
    . 
    . 
    . 
} 

희망, 이것이 당신이 찾고있는 것입니다.

0

나는 다음과 같은 방법으로 그것을 할 것 : 1) 내가 알고있는 것처럼, 뷰 속성은 카운터 컬럼에 해당하는 TrackerReports[] resultListtrackerReportList[0] 항목 2)의 전체 복사본의 배열입니다 보자. 그렇다면

foreach(report in resultList) 
{ 
    report.Views = trackerReportList.Sum(reports => reports.Single(r => r.MilestoneId == report.MilestoneId).Views); 
} 
3

다음은 Linq를 사용하는 방법입니다.

  1. 첫째, 당신은 ArraysList보다는 하나의 목록에있는 데이터를 얻을 싶어요. SelectMany으로이 작업을 수행 할 수 있습니다.

    trackerReportList.SelectMany(c => c) 마지막으로, 당신은 우리가 원하는 형식으로 그룹화 프로젝트 List<TrackerReport[]>()

    group p by new { 
          ID = p.MilestoneId, 
          Name = p.Name, 
          Url = p.Url} into g 
    
  2. 그런 다음 그룹 관련 열을 기준으로 개체/열

  3. IEnumerable<TrackerReport>로 평평. CounterAdding 각 그룹의 개체 수집에 대해 Views으로 얻습니다.

select new { 
    ... 
}; 
이 모두 함께 퍼팅 :

var report = from p in trackerReportList.SelectMany(c => c) 
      group p by new { 
       ID = p.MilestoneId, 
       Name = p.Name, 
       Url = p.Url} into g 
      select new { 
       ID = g.Key.ID, 
       Name = g.Key.Name, 
       Url = g.Key.Url, 
       Counter = g.Sum(c => c.Views) 
      }; 
+0

TNX 많이 나는 이후에이 솔루션을 보았다 이미 다른 것을 시도했다. – Attila