2016-07-12 55 views
0

好的人,在抨擊之前,這與我所研究的有點不同。檢查是否通過選擇最後一個行實體框架

目前,我有以下代碼:

public async Task<ParticipantTournament> GetParticipantTournamentByDescending(int tournamentId, int participantId) 
     { 
      var response = await _dbRepositories.TournamentParticipantMatchRepository 
       .Where(x => x.TournamentId == tournamentId) 
       .OrderByDescending(y => y.TournamentMatch.RoundNumber) 
       .ThenByDescending(y => y.TournamentMatch.Id) 
       .Include(x => x.Tournament) 
       .Include(x => x.Participant1) 
       .Include(x => x.Participant2) 
       .Include(x => x.TournamentMatch) 
       .Select(z => new TournamentParticipantMatchLogicDto 
       { 


        IsLastMatch = OneTrue() // <==== Problem here, 
        TournamentParticipantMatch = z 


       }).Where(x => (x.TournamentParticipantMatch.Participant1Id == participantId || x.TournamentParticipantMatch.Participant2Id == participantId)) 
       .ToListAsync(); 
      return new ParticipantTournament 
      { 
       ParticipantMatches = response, 
      }; 


     } 
     /** 
     * This may be something super dumb. But I couldnt' come up with something better. 
     * How do I detect the latest match? 
     * http://stackoverflow.com/questions/14687136/check-if-record-is-last-or-first-in-list-with-linq 
     * 
     * Well, after digging a little bit, I've found that this is not possible :o 
     * */ 
     private bool OneTrue() 
     { 
      if (!IsLast) return false; 
      IsLast = false; 
      return true; 
     } 

我建立一個比賽的平臺。我需要知道哪個是最後一場比賽,所以我可以給玩家5輪而不是3個。而不是創建一個新的列,並填寫虛假或真實的,我決定過濾它。我認爲我可以利用LINQ的延期執行:

  1. 我會從錦標賽中選擇整個數據集。
  2. 然後我會按降序排序,並選擇第一行作爲最後一行。 (所有匹配都是按順序插入的,所以最大的ID是最後一個)
    1. 然後過濾掉哪些來自用戶,哪些不是。

可能的解決方案,我認爲它可以工作: - 創建一個布爾值列,將舉行最後的比賽「真」值。 - 使用規範模式(我不知道如何應用在這種情況下,嘗試使用表達式和Func,但無法正確映射它們) - 加載所有ID並選擇這些ID中的最後一個。將這些ID與所有用戶擁有的Ids進行比較。不幸的是,這會爲數據庫增加一個額外的往返。

我該怎麼辦?

謝謝!

P.S:OneTrue()方法做它做的事情,它返回true一次,然後返回false。 (沒有找到一個快速谷歌搜索後,其他東西)

編輯 特此說明: enter image description here

表顯示我公司目前擁有的數據的模擬。我只需要提取當前用戶需要的內容,所以我不需要其他兩行(您可以在表#2中看到)。一旦我選擇了這兩行,我排除了其他可能有最後一個匹配的行,但只選擇了這兩行,我不知道。我試圖從第一次嘗試查詢它來保存任何冗餘。我知道最後的比賽ID是最後一場比賽

所以我想要做的是按降序排列它們(因爲它們是有序的),並選擇最後一個作爲最後一場比賽。

+0

你的代碼不工作的原因是你不能在查詢中調用方法,因爲該方法不能被轉換爲sql。你可以通過在'.Select()'之前調用'.ToList()'來實現查詢到內存。Where()'之前的'.ToList()'也是。 –

+0

不完全確定我理解你的查詢,但是你不能只是省略'IsLastMatch = OneTrue()'(所以它默認爲'false')並且在查詢之後,'response.First()。IsLastMatch = true;'(假設你的查詢總是返回至少一個'TournamentParticipantMatchLogicDto')? –

+0

@StephenMuecke:謝謝你的評論!我剛剛更新了我的問題。我想要做的是避免儘可能多的往返數據庫。我試圖將所有內容都放在一個查詢中。如果這是不可能的,我會提取所有的值,並做一個後過濾器。 –

回答

1

你能不只是查詢數據子集的使用LINQ的回報之後,如:

var temp = from e in _dbRepositories.TournamentParticipantMatchRepository 
      where (from f in _dbRepositories.TournamentParticipantMatchRepository 
        where f.TournamentId == tournamentId) 
        .Include(x => x.Tournament) 
      .Include(x => x.Participant1) 
      .Include(x => x.Participant2) 
      .Include(x => x.TournamentMatch) 
      .Select(z => new TournamentParticipantMatchLogicDto 
      { 


       IsLastMatch = false, // <==== Problem here, 
       TournamentParticipantMatch = z 


      }).Where(x => (x.TournamentParticipantMatch.Participant1Id == participantId || x.TournamentParticipantMatch.Participant2Id == participantId)) 
      .ToListAsync(); 

int maxResult= temp.Max(t => t.TournamentParticipantMatch.Id); 
var update= temp.SingleOrDefault(x => x.TournamentParticipantMatch.Id== maxResult); 

if(update!= null) 
    update.IsLastMatch= true; 
+0

謝謝!我可以做到!我只會提取比我真正需要的更多的行,所以這就是爲什麼我想在提取數據之前進行過濾的原因。 –

0

這是我落得這樣做。請如果你看到任何改進讓我知道!

public async Task<ParticipantTournament> GetParticipantTournamentByDescending(int tournamentId, int participantId) 
    { 
     var lastMatchId = await _dbRepositories.TournamentParticipantMatchRepository 
      .Where(x => x.TournamentId == tournamentId) 
      .OrderByDescending(y => y.TournamentMatch.RoundNumber) 
      .ThenByDescending(y => y.TournamentMatch.Id) 
      .Select(x => x.Id).FirstOrDefaultAsync(); 

     var response = await _dbRepositories.TournamentParticipantMatchRepository 
      .Where(x => x.TournamentId == tournamentId) 
      .Where(x => (x.Participant1Id == participantId || x.Participant2Id == participantId)) 
      .Include(x => x.Tournament) 
      .Include(x => x.Participant1) 
      .Include(x => x.Participant2) 
      .Include(x => x.TournamentMatch) 
      .ToListAsync(); 

      var logic = response.Select(z=> new TournamentParticipantMatchLogicDto 
      { 
       IsLastMatch = z.Id == lastMatchId, 
       TournamentParticipantMatch = z 
      }) 
      ; 
     return new ParticipantTournament 
     { 
      ParticipantMatches = logic, 
     }; 


    }