簡體   English   中英

將SQL語句轉換為LINQ-To-SQL

[英]Convert an SQL statement into LINQ-To-SQL

我是否可以將以下內容轉換為LINQ語句。

SELECT reports.* FROM [dbo].[ReportLists] rl
INNER JOIN [dbo].[ReportItems] ri ON rl.Id = ri.ReportListId
INNER JOIN [dbo].[Reports] reports ON ri.Id = reports.ReportItemId
WHERE
    reports.createdDate
IN (
    SELECT 
        MAX(report_max_dates.createdDate) 
    FROM 
        [dbo].[Reports] report_max_dates
    GROUP BY 
        report_max_dates.seedLot
    )

目前我有這個:

db.ReportLists.Select(rl => db.ReportItems
                            .Where(ri => ri.ReportListId == rl.Id)
                            .Select(ri => db.Reports
                                          .Where(r => r.ReportItemId == ri.Id)
                                          .GroupBy(r => new { r.seedLot })
                                          .Select(g => g.OrderByDescending(x => x.createdDate).FirstOrDefault())));

上面的LINQ的問題是它返回標題已更改的條目。 在數據庫中,我保留了所有記錄的歷史記錄(因此需要第一個創建日期順序下降。當我將報告從標題x更改為標題y時,它顯示在兩個標題下,當我只想要最新記錄時因此是標題y下的那個。

編輯很抱歉缺乏細節。 我有一個報告表,其中包含有關報告的信息(種子圖是標識符)。 每當編輯報告時,都會插入新記錄(與更新舊記錄),以便保留歷史記錄。 在這種情況下,createdDate的max條目表示報告是要顯示的最新記錄。 然后將報告分組為標題或ReportItems。 這些報告項目包含標題和相關報告。 這些reportItem保存在ReportList中,這樣我就可以以所需的格式打印出JSON,並且只包含一個由ReportItems鏈接的狀態列和id。

如果報告從標題a移動到標題b,則輸入新記錄,標題外鍵鏈接到更改為的標題。 當發生這種情況時,上面給出的LINQ返回每個ReportItem下的記錄,它只返回標題b的最新條目(來自上面的例子)。 除此之外,LINQ語句僅返回createdDate的最新記錄。

這是我的類結構(也模仿數據庫結構)

public class ReportList {
    public int Id {get;set;}
    public string status {get;set;}
    public List<ReportItem> {get;set;}
}

public class ReportItem {
    public int Id {get;set}
    public string title {get;set;}
    public List<Report> {get;set;}
}

public class Report {
    public int Id {get;set;}
    public string Lot {get;set;}
    ... Other data ...
    public DateTime createdDate {get;set;}
}

謝謝,德曼

如果我理解正確,那么你想要seedLot的最新報告,那么我將使用下一個:

from r in Reports
group r by r.CreateDate into g
select g.OrderByDescending(r1=>r1.CreateDate).FirstOrDefault()

不完全確定為什么如果不將它們包含在結果中,您需要ReportItem和ReportList,您可以使用Report的導航屬性遍歷它們。

啊。 我知道了。 您的內部聯接正在剔除ReportItems表中沒有Id的記錄和ReportLists表中沒有Id的ReportItems。 由於您沒有在Linq中使用內部聯接語法,因此它們不相同。 你試過這個:

var reports = from rl in db.ReportLists
              from ri in rl.ReportItems 
              from r in ri.Reports
              where (
                  from report in db.Reports
                  group report by report.seedLot into g
                  select g.Max(rep => rep.createdDate)).Contains(r.CreatedDate)
              select rl;

我不是百分之百,我已經使用Contains在該組中獲得了正確的語法(我不會在日常工作中進行大量的分組)。 如果LINQ提供程序不支持Max(或包含,雖然它應該),那么它將拉動客戶端的東西,這是很多數據推送線。

你提供的細節使它更清晰,雖然不完全,所以我會給出兩個選擇。 導航屬性派上用場,因為現在可以使用非常簡潔的綜合語法:

from rl in context.ReportLists
from ri in rl.ReportItems
from r in ri.Reports
group r by r.Lot into g
select g.OrderByDescending(x => x.createdDate).FirstOrDefault()

或者(因為您似乎按ReportItemsTitle ReportItems ):

from rl in context.ReportLists
from ri in rl.ReportItems
group ri by ri.Title into g
select g.Select(x => x.Reports
                      .OrderByDescending(x => x.createdDate).FirstOrDefault())

在引擎蓋下,這也產生SQL連接,但你不需要笨拙的語法。 在linq流利的語法中,它歸結為SelectMany() s。

如你所見,我仍然無法弄清楚LotTitle的作用,但我希望替代品可以根據您自己的規格提供一些實質內容。

將數據庫模式更改為sorta將其展平,取消了很多分支。

報告現在是根,我只有一個附加到報告的標題表。

感謝大家的建議!

暫無
暫無

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

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