2017-01-24 57 views
2

我很努力地將MySQL查詢轉換爲C#中的linq語法(用於實體框架)。 MySQL查詢看起來像這樣:Linq在select中選擇

SELECT * 
FROM Availability as tableData 
WHERE ID = (
SELECT Availability.ID 
FROM Availability 
WHERE Availability.FrameID = tableData.FrameID 
ORDER BY Availability.Date DESC limit 1) 

我不知道如何轉換此部分FROM table AS someName

到目前爲止,我有唯一的解決辦法,是執行原始的SQL查詢,如:

dataContext.Availability.SqlQuery("SELECT * FROM Availability as tableData WHERE ID = (SELECT ID FROM Availability WHERE FrameID = tableData.FrameID ORDER BY Availability.Date DESC limit 1)").ToArray(); 

但它會很高興地知道,如果LINQ可以提供這樣的查詢。

在此先感謝您的答案!

+1

這裏子查詢的要點是什麼? –

+0

對於每個FrameID,我只需要一條記錄(插入的最大日期) – user3550149

+0

通過一個ID獲取一個實體將如下簡單:entity = context.Table.Find(id);在Linq。我錯過了什麼嗎? –

回答

4

如果你需要爲每個幀ID只有最新的記錄,然後使用分組:

dataContext.Availability 
    .GroupBy(a => a.FrameID) 
    .Select(g => g.OrderByDescending(a => a.Date).FirstOrDefault()); 

生產需要此查詢結果,但生成的sql會有點不同。它看起來像

SELECT /* limit1 fields */ 
FROM (
    SELECT DISTINCT tableData.FrameID 
    FROM Availability as tableData) AS distinct1 
OUTER APPLY (
    SELECT TOP(1) /* project1 fields */ 
    FROM (SELECT /* extent1 fields */ 
      FROM Availability AS extent1 
      WHERE Availability.FrameID = distinct1.FrameID) AS project1 
    ORDER BY project1.Date DESC) AS limit1 

注:First()擴展不受EF

支持
2

採取一切Avilabilities,按FrameId,按日期順序各組,取每組的第一個條目。 ToList()在最後獲取所有結果並將它們放入List中。

var tableDate = dataContext.Availability 
       .GroupBy(x => x.FrameId) 
       .Select(x => x.OrderByDescending(y => y.Date).FirstOrDefault()) 
       .ToList(); 
+0

as @SergeyBerezovskiy發佈First()不受EF的支持。但是用FirstOrDefault()它可以工作。謝謝! – user3550149

1

是的Linq可以做到這一點,但你需要有一個linq應該運行的起始序列。通常情況下,這個序列與您的表格類型相同,在您的情況下可用性。

從SQL據我瞭解,在有效性的表中的每個記錄至少屬性標識,FrameId和日期:

class Availability 
{ 
    public int Id {get; set;} 
    public int FrameId {get; set; 
    public DateTime Date {get; set;} 
} 

當然,這也可以是一個匿名類型。重要的是,你必須以某種方式有項目,這些性質的序列:

IQueryable<Availability> availabilities = ... 

您寫道:每

我只需要一個記錄(與插入的最大日)FrameID

因此,每個可用性都有一個FrameId,並且您希望每個FrameId具有最高Date值的記錄。

你可以使用Enumerable.GroupBy和group by FrameId

var groupsWithSameFrameId = availabilities.GroupBy(availability => availability.FrameId); 

結果是組的序列。每個組都包含具有相同FrameId的所有可用性的序列。換句話說:如果你創建了一個組,你將擁有一個具有FrameId值的group.Key和一系列具有此FrameId值的所有可用性。

我們不會使用group.Key。 如果您在按日期降序排序每組中元素的順序,採取的第一個元素,你必須從每一個組的最高值

var recordWithMaxDateOfInsert = groupsWithSameFrameId 
    .Select(group => group.OrderByDescending(groupElement => groupElement.Date) 
    .First(); 

組排序的所有元素的日期通過降序日期值並採取排序組的第一個元素。

結果:根據您的原始可用性,您對每個frameId具有最高值的可用性。