2016-02-29 33 views
1

在下面的linq查詢中,我想添加一個屬性,獲取以前的Department以及當前的Department。 回報以下LINQ查詢:c#linq獲取當前值和以前的值

EffectiveDate EmployeeID Department 
11/4/2012  10   0000 
1/14/2013  10   9121 
2/2/2016  10   9123 

我怎麼能顯示前Department旁邊當前Department這樣嗎?

EffectiveDate EmployeeID Department PreviousDepartment 
11/4/2012  10   0000  null 
1/14/2013  10   9121  0000 
2/2/2016  10   9123  9121 

下面是當前查詢

var users = from s in userTable 
      where s.EmployeeID == "10" 
      group new {s} by new { s.EmployeeID, s.Department} into g 
      select new 
      { 
       EffectiveDate = g.Max(m => m.s.EffectiveDate), 
       EmployeeID = g.Key.EmployeeID, 
       Department = g.Key.Department 
       //PreviousDepartment = ??? 
      }; 

感謝您的幫助

+0

是否有一個原因,你爲什麼'組合新{s}'而不是'組s'? –

回答

0

一種方式來做到這一點是存儲在內存中的數據,然後修改它像這樣:

var users = from s in userTable 
      where s.EmployeeID == "10" 
      group new {s} by new { s.EmployeeID, s.Department} into g 
      select new MyClass 
      { 
       EffectiveDate = g.Max(m => m.s.EffectiveDate), 
       EmployeeID = g.Key.EmployeeID, 
       Department = g.Key.Department 
       PreviousDepartment = null 
      }; 

var result = users.ToList(); 

for(int i = 1; i < result.Count; i++) 
{ 
    result[i].PreviousDepartment = result[i-1].Department; 
} 

請注意,該代碼正在生成MyClass的新實例,而不是匿名因爲匿名類型屬性是隻讀的。確保你創建了具有正確屬性的類。

+0

謝謝,雅各布。這完成了我所需要的。關於你的關於「group new {s}」的問題,我在Linqpad中使用了這個問題,因爲我收到了「group s」的錯誤。 – jaykzoo

0

如果使用交互式擴展(NuGet包IX-主),你可以做到以下幾點:

var users = 
    userTable 
    .Where(x => x.EmployeeID == "100") 
    .GroupBy(x => new { x.EmployeeID, x.Department }) 
    .Select(x => new 
     { 
      EffectiveDate = x.Max(m => m.EffectiveDate), 
      EmployeeID = x.Key.EmployeeID, 
      Department = x.Key.Department 
     }) 
    .OrderBy(x => x.EffectiveDate) 
    .AsEnumerable() 
    .Scan(
     new 
     { 
      EffectiveDate = default(DateTime), 
      EmployeeID = default(string), 
      Department = default(string), 
      PreviousDepartment = default(string) 
     }, 
     (a, x) => new 
     { 
      EffectiveDate = x.EffectiveDate, 
      EmployeeID = x.EmployeeID, 
      Department = x.Department, 
      PreviousDepartment = a.Department 
     }); 

的好處是,你堅持的聲明性編程風格。缺點是它比內存中的數據操作更詳細,可能更難讀取。哦,你可能需要安裝一個NuGet包。對我而言,這不是一個問題,因爲我不認爲我沒有添加Ix-Main就開始任何項目。

Ix-Main,如果沒有它,永遠不要離開家。

+0

謝謝你的回答,傑森。不幸的是,如果不經過繁文red節,我們公司不能安裝擴展程序。 – jaykzoo

1

您可以使用LINQ中的Zip方法生成當前對和先前對。一個缺點是,它會枚舉輸入兩次(這可能是一個問題,如果它來自數據庫),但另一方面,它不會將整個輸入保存在內存中,並且它是懶惰的(即,您沒有消耗全部)。

例如,使用INT值作爲演示:

[TestMethod] 
public void CurrentAndPrevious() 
{ 
    var input = new int[] { 1, 2, 3, 4, 5 }; 

    var output = Enumerable.Repeat(0,1) // an initial zero value 
     .Concat(input)     // followed by the list 
              // zipped with the list 
     .Zip(input, (x, y) => new {current = y, previous = x}); 

    // a test that passes (using FluentAssertions syntax) 
    string.Join(",", output.Select(x => $"({x.current},{x.previous})")) 
     .Should().Be("(1,0),(2,1),(3,2),(4,3),(5,4)"); 
} 
+0

謝謝你的回答,伊恩。我在使用我的列表時遇到錯誤,因此需要花更多時間來查看它。獲取.Concat擴展方法的錯誤,即使當我運行你的代碼時,我也不會。 – jaykzoo

0

甲方法語法實現它。

var result = userTable.Select((x, i) => { Department j = null ; if (i>0) j = userTable.ElementAt(i-1).Department; return new { x.EffectiveDate , x.EmployeeID , x.Department , j};}); 
+0

感謝您的解決方案,Shashwat,我收到第一個部門參考的「類型或命名空間部門找不到」的錯誤。 – jaykzoo