避免使用Linq查询+可选参数重复代码
本文关键字:参数 代码 Linq 查询 | 更新日期: 2023-09-27 18:20:38
给定代码:
/// <summary>
/// Get a games high scores
/// </summary>
public static List<Score> GetGameHighScores(int gameID, HighScoreType type, int? skip = null, int? take = null)
{
var r = new List<Score>();
using (var db = new ArcadeContext())
{
var q = new List<ArcadeScore>();
if (skip != null && take != null)
{
switch (type)
{
case HighScoreType.ScoreRank:
q =
db.ArcadeScores.Where(c => c.GameID == gameID && c.ScoreRank > 0)
.OrderBy(c => c.ScoreRank)
.Skip(skip.Value)
.Take(take.Value)
.ToList();
break;
case HighScoreType.UserRank:
q =
db.ArcadeScores.Where(c => c.GameID == gameID && c.UserRank > 0)
.OrderBy(c => c.UserRank)
.Skip(skip.Value)
.Take(take.Value)
.ToList();
break;
}
}
else
{
switch (type)
{
case HighScoreType.ScoreRank:
q =
db.ArcadeScores.Where(c => c.GameID == gameID && c.ScoreRank > 0)
.OrderBy(c => c.ScoreRank)
.ToList();
break;
case HighScoreType.UserRank:
q =
db.ArcadeScores.Where(c => c.GameID == gameID && c.UserRank > 0)
.OrderBy(c => c.UserRank)
.ToList();
break;
}
}
r.AddRange(q.Select(arcadeScore => new Score(arcadeScore)));
}
return r;
}
如果skip
和take
是可选参数(用于需要分页时),那么在不重复上述内容的情况下获取正确记录的最佳方法是什么?
不要在四个独立的查询之间切换,而是根据您的条件构建单个查询:
IQueryable<Score> query = db.ArcadeScores.Where(c => c.GameID == gameID);
switch(type)
{
case HighScoreType.ScoreRank:
query = query.Where(c => c.ScoreRank > 0).OrderBy(c => c.ScoreRank);
break;
case HighScoreType.UserRank:
query = query.Where(c => c.UserRank > 0).OrderBy(c => c.UserRank);
break;
}
if (skip.HasValue && take.HasValue)
query = query.Skip(skip.Value).Take(take.Value);
return query.ToList();
假设在调用ToList
之前不会执行IEnumerable
,您可以简单地将其移动到switch语句之外,然后调用ToList
只需使用联合运算符即可提供默认值:
.Skip(skip ?? 0)
.Take(take ?? int.MaxValue)
也许,将其提取到一个方法中,这样您就只能在OrderBy和Skip想要分页的时候调用它们。
db.ArcadeScores.Where(c => c.GameID == gameID && c.ScoreRank > 0)
.OrderBy(c => c.ScoreRank).
db.ArcadeScores.Where(c => c.GameID == gameID && c.UserRank > 0)
.OrderBy(c => c.UserRank)
进入
private IEnumerable<ArcadeScore> GetArcadeOverallScore(int gameId)
{
return db.ArcadeScores.Where(c => c.GameID == gameID && c.ScoreRank > 0)
.OrderBy(c => c.ScoreRank)
}
private IEnumerable<ArcadeScore> GetArcadeUserScore(int gameId)
{
return db.ArcadeScores.Where(c => c.GameID == gameID && c.UserRank > 0)
.OrderBy(c => c.UserRank)
}