public async Task<CourseListResultViewModel> GetCourseAsync(
int pageId = 1,
string filter = "",
string getType = "all",
string orderByType = "date",
int startPrice = 0,
int endPrice = 0,
List<int>? selectedGroups = null,
int take = 0)
{
if (take <= 0)
take = 16;
if (pageId < 1)
pageId = 1;
if (startPrice < 0)
startPrice = 0;
if (endPrice < 0)
endPrice = 0;
if (startPrice > 0 &&
endPrice > 0 &&
startPrice > endPrice)
{
(startPrice, endPrice) = (endPrice, startPrice);
}
IQueryable<Course> result =
_context.Courses.AsNoTracking();
// Search
if (!string.IsNullOrWhiteSpace(filter))
{
result = result.Where(c =>
c.CourseTitle.Contains(filter));
}
// Type
switch (getType)
{
case "buy":
result = result.Where(c =>
c.CoursePrice != 0);
break;
case "free":
result = result.Where(c =>
c.CoursePrice == 0);
break;
}
// Price
if (startPrice > 0)
{
result = result.Where(c =>
c.CoursePrice >= startPrice);
}
if (endPrice > 0)
{
result = result.Where(c =>
c.CoursePrice <= endPrice);
}
// Groups
if (selectedGroups != null &&
selectedGroups.Count > 0)
{
var groupIds = selectedGroups;
result = result.Where(c =>
groupIds.Contains(c.GroupId) ||
(c.SubGroup != null &&
groupIds.Contains(c.SubGroup.Value)));
}
// Count asynchronously
int totalCount = await result.CountAsync();
int pageCount = totalCount == 0
? 0
: (int)Math.Ceiling(
totalCount / (double)take);
// Fix invalid page
if (pageCount > 0 && pageId > pageCount)
{
pageId = pageCount;
}
// Ordering
IQueryable<Course> ordered =
orderByType == "updatedate"
? result
.OrderByDescending(c => c.UpdateDate)
.ThenByDescending(c => c.CourseId)
: result
.OrderByDescending(c => c.CreateDate)
.ThenByDescending(c => c.CourseId);
int skip = (pageId - 1) * take;
// Get page asynchronously
var raw = await ordered
.Select(c => new
{
c.CourseId,
c.CourseTitle,
c.CourseImageName,
c.CoursePrice,
c.TeacherId,
EpisodeTicks = c.CourseEpisodes
.Select(e => e.EpisodeTime.Ticks)
})
.Skip(skip)
.Take(take)
.ToListAsync();
// Get teachers
var teacherIds = raw
.Select(r => r.TeacherId)
.Distinct()
.ToList();
var teacherNames = await _context.UserRoles
.Where(r => teacherIds.Contains(r.UserId))
.Select(r => new
{
r.UserId,
r.User.FullName
})
.Distinct()
.ToListAsync();
var teacherDictionary = teacherNames
.GroupBy(r => r.UserId)
.ToDictionary(
g => g.Key,
g => $"{g.First().FullName}".Trim());
// Map result
var query = raw
.Select(c => new ShowCourseListItemViewModel
{
CourseId = c.CourseId,
Title = c.CourseTitle,
ImageName = c.CourseImageName,
Price = c.CoursePrice,
TeacherName =
teacherDictionary.TryGetValue(
c.TeacherId,
out var teacherName)
? teacherName
: null,
TotalTime =
new TimeSpan(c.EpisodeTicks.Sum())
})
.ToList();
return new CourseListResultViewModel
{
Items = query,
TotalCount = totalCount,
PageCount = pageCount,
CurrentPage = pageId
};
}استاد بنظرتون خوب نوشتم این قسمت رو و از async , await استفاده کردم که باعث بشه در زمان انتظار دیتابیس آزاد بشه ؟