簡體   English   中英

C#LINQ與實體一對多關系:顯示最后的日志條目數據時出現問題

[英]C# LINQ to Entities One-To-Many relationship: Problem displaying last log entry data

我有一個帶有兩個表的Web應用程序來跟蹤用戶份額。 股份必須經過批准,才能進行一系列狀態更改。 每個狀態更改都記錄在日志中並加蓋時間戳。 當前狀態始終是該特定共享的日志中的最后一個條目。

以下是實體(簡潔):

共享:ShareID用戶名

ShareLogs:LogID ShareID創建日期狀態

我正在嘗試根據上一個日志條目獲取具有當前狀態的共享列表。 這是返回正確結果的SQL查詢,但我想使用LINQ進行此操作。

SELECT s.ShareID, s.UserName, sl.Code, sl.CreatedDate
FROM Shares s
INNER JOIN 
(
SELECT s.ShareID, s.Code, s.CreatedDate
    FROM ShareLogs sl
    INNER JOIN (SELECT ShareID, MAX(CreatedDate) logDate FROM ShareLogs GROUP BY ShareID) sl2
        ON sl.ShareID = sl2.ShareID AND sl.CreatedDate = sl2.logDate) psl1
ON s.ShareID = sl1.ShareID
ORDER BY s.ShareID

我寫了一個看起來不錯的LINQ查詢,但是我覺得應該有更好的方法,因為這個查詢看起來很糟糕。

var query = from list in
(from s in context.Shares
join sl in context.ShareLogs on s.ShareID equals sl.ShareID
where sl.CreatedDate == s.ShareLogs.Max(e => e.CreatedDate)
select new
{
 share = s
 status = sl.Code,
 processDate = sl.CreatedDate
}).Where(e => e.status == 2 || e.status == 3)
select list;

您可以嘗試進行聯接,然后對除ShareID以外的所有行進行分組,然后僅獲取日期最大的共享。 例如:

var shareList = context.Shares;
var shareLogList = context.ShareLogs;
var join = shareList.Join(shareLogList, o=>o.ShareID, i=>i.ShareID, s=>new{o.ShareID, o.UserName,i.LogID, i.CreatedDate, i.Status});
var query = join.GroupBy(g=>new{g.ShareID,g.UserName}, (key,lines)=>new{key.ShareID, Status = lines.Max(m=>m.CreatedDate).Status});

那應該做! 如果願意,可以將其合並為一個語句,為了清楚起見,我將它們分開。

var query = (from s in context.Shares
            let latestOrder = s.ShareLogs                                             
                                         .OrderByDescending(sl => sl.CreatedDate)
                                         .First()
            select new 
            {
                share = s,
                status = latestOrder.Code,
                processDate = latestOrder.CreatedDate
            }).Where(sl => sl.status == 2 || sl.status ==3);

讓我知道您是否認為這是一種改進。

編輯:我不是100%知道您需要在哪里過濾器,所以我離開了它。 我認為Let語句中可能實際上需要它。 或者我們可以將其移至Comprehension語法中以使其更加一致。

我更喜歡方法語法,所以這是我的答案。 請注意,我也在進行分組依據,而不是聯接。

 context.ShareLogs.GroupBy(log => log.ShareID)
     .Select(g => g.Logs.Single(log => 
         log.CreatedDate == g.Logs.Max(g => g.CreatedDate)))         
     .Select(l => new { Share = l.Share, Status = l.Code, Date = l.CreatedDate });

您應該能夠對ShareLogs進行分組,以確定正確的ShareLog對象(其中包含Code,Date和ShareID),然后使用導航屬性log.Share檢索Share。

據我所知,不需要聯接,因為LINQ通常通過導航屬性將其隱藏起來。

暫無
暫無

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

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