[英]Convert SQL statement to Linq-to-SQL with 2 columns with a count(*) not working
[英]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()
或者(因為您似乎按ReportItems
的Title
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。
如你所見,我仍然無法弄清楚Lot
和Title
的作用,但我希望替代品可以根據您自己的規格提供一些實質內容。
將數據庫模式更改為sorta將其展平,取消了很多分支。
報告現在是根,我只有一個附加到報告的標題表。
感謝大家的建議!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.