簡體   English   中英

Linq等效於分組選擇

[英]Linq equivalent for grouping select

從像這樣的傳統SQL語句中:

SELECT Id, Owner, MIN(CallTime) 
FROM traffic 
WHERE CallType = "IN" 
GROUP BY Owner;

其中CallTime是日期時間字段,我想要的是屬於每個Owner的最舊記錄。

如何使用Linq做到這一點?

這是我的嘗試(我使用的是實體框架, context是實體實例):

var query = context.traffic.Where(t => t.CallType == "IN");
var results = query
    .GroupBy(t => t.Owner)
    .Select(g => new { CallTime = g.Min(h => h.CallTime) });

但是我還需要訪問IdOwner字段,而現在我只能訪問CallTime

您無法訪問給定代碼中的ID,因為您正在按所有者分組,並且該組的密鑰將是所有者而不是“流量”對象。

如果按流量對象分組,則需要某種方式來告訴groupBy如何正確比較它們(即按所有者分組)這可以通過IEqualityComparer來完成

例如

private class Traffic {
    public int Id { get; set; }
    public string Owner { get; set; }
    public DateTime CallTime { get; set; }
}

private class TrafficEquaityComparer : IEqualityComparer<Traffic> {
    public bool Equals(Traffic x, Traffic y) {
            return x.Owner == y.Owner;
    }

    public int GetHashCode(Traffic obj) {
        return obj.Owner.GetHashCode();
    }
}


private static TrafficEquaityComparer TrafficEqCmp = new TrafficEquaityComparer();

private Traffic[] src = new Traffic[]{
   new Traffic{Id = 1, Owner = "A", CallTime = new DateTime(2012,1,1)},  // oldest
   new Traffic{Id = 2, Owner = "A", CallTime = new DateTime(2012,2,1)},
   new Traffic{Id = 3, Owner = "A", CallTime = new DateTime(2012,3,1)},
   new Traffic{Id = 4, Owner = "B", CallTime = new DateTime(2011,3,1)},
   new Traffic{Id = 5, Owner = "B", CallTime = new DateTime(2011,1,1)},   //oldest
   new Traffic{Id = 6, Owner = "B", CallTime = new DateTime(2011,2,1)},
};

[TestMethod]
public void GetMinCalls() {
     var results = src.GroupBy(ts => ts, TrafficEqCmp)
                        .Select(grp => {
                            var oldest = grp.OrderBy(g => g.CallTime).First();
                            return new { Id = oldest.Id, 
                                         Owner = grp.Key.Owner, 
                                         CallTime = oldest.CallTime };

                        });    }

這給

ID : Owner : MinCallTime

1 :    A   :  (01/01/2012 00:00:00)
5 :    B   :  (01/01/2011 00:00:00)

作為結果。

您的SQL查詢對我而言無效:您使用的是Id ,但未按其分組。 我假設您想按IdOwner分組?

var results = query
     .GroupBy(t => new {Id = t.Id, Owner = t.Owner})
     .Select(g => new { Id = g.Key.Id, Owner = g.Key.Owner, CallTime = g.Min(h => h.CallTime) })
     .ToList();

如果要獲取最舊的(最小的) ID而不是按其分組:

var results = query
     .GroupBy(t => t.Owner)
     .Select(g => new { Id = g.Min(x => x.Id), Owner = g.Key, CallTime = g.Min(h => h.CallTime) })
     .ToList();

// custQueryIEnumerable<IGrouping<string, Customer>>

var custQuery =  
    from cust in customers  
    group cust by cust.City into custGroup  
    where custGroup.Count() > 2  
    orderby custGroup.Key  
    select custGroup;  

在該示例中,選擇組

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM