#217 actual counting

This commit is contained in:
Hamid Reza Mohammadi 2021-10-03 14:29:52 +03:30
parent d36060161f
commit 73f585253a
2 changed files with 156 additions and 3 deletions

View File

@ -9917,16 +9917,28 @@
</summary>
<returns></returns>
</member>
<member name="M:RMuseum.Services.Implementation.GanjoorNumberingService.Count(System.Int32)">
<summary>
start counting
</summary>
<returns></returns>
</member>
<member name="F:RMuseum.Services.Implementation.GanjoorNumberingService._context">
<summary>
Database Context
</summary>
</member>
<member name="M:RMuseum.Services.Implementation.GanjoorNumberingService.#ctor(RMuseum.DbContext.RMuseumDbContext)">
<member name="F:RMuseum.Services.Implementation.GanjoorNumberingService._backgroundTaskQueue">
<summary>
Background Task Queue Instance
</summary>
</member>
<member name="M:RMuseum.Services.Implementation.GanjoorNumberingService.#ctor(RMuseum.DbContext.RMuseumDbContext,RSecurityBackend.Services.IBackgroundTaskQueue)">
<summary>
constructor
</summary>
<param name="context"></param>
<param name="backgroundTaskQueue"></param>
</member>
<member name="T:RMuseum.Services.Implementation.GanjoorService">
<summary>

View File

@ -2,7 +2,10 @@
using RMuseum.DbContext;
using RMuseum.Models.Ganjoor;
using RSecurityBackend.Models.Generic;
using RSecurityBackend.Services;
using RSecurityBackend.Services.Implementation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
@ -30,6 +33,7 @@ namespace RMuseum.Services.Implementation
{
_context.GanjoorNumberings.Add(numbering);
await _context.SaveChangesAsync();
Count(numbering.Id); //start counting
return new RServiceResult<GanjoorNumbering>(numbering);
}
catch (Exception exp)
@ -144,7 +148,7 @@ namespace RMuseum.Services.Implementation
{
try
{
var subcatIds = await _context.GanjoorCategories.Where(c => c.ParentId == parentCatId).Select(c => c.Id).ToListAsync();
var subcatIds = await _context.GanjoorCategories.AsNoTracking().Where(c => c.ParentId == parentCatId).Select(c => c.Id).ToListAsync();
return new RServiceResult<GanjoorNumbering[]>(await _context.GanjoorNumberings.Where(n => subcatIds.Contains(n.StartCatId)).OrderBy(l => l.Id).ToArrayAsync());
}
catch (Exception exp)
@ -153,18 +157,155 @@ namespace RMuseum.Services.Implementation
}
}
private async Task<List<GanjoorCat>> _FindAllSubCategories(RMuseumDbContext context, int catId)
{
List<GanjoorCat> cats = new List<GanjoorCat>();
foreach (var cat in await context.GanjoorCategories.AsNoTracking().Where(c => c.ParentId == catId).OrderBy(c => c.Id).ToListAsync())
{
cats.Add(cat);
var subCats = await _FindAllSubCategories(context, cat.Id);
if(subCats.Count > 0)
{
cats.AddRange(subCats);
}
}
return cats;
}
private async Task<List<GanjoorCat>> _FindCategoryRanges(RMuseumDbContext context, GanjoorCat startCat, int endCatId)
{
var parents = await context.GanjoorCategories.AsNoTracking().Where(c => c.ParentId == startCat.ParentId && c.Id >= startCat.Id && c.Id <= endCatId).OrderBy(c => c.Id).ToListAsync();
List<GanjoorCat> cats = new List<GanjoorCat>();
foreach(GanjoorCat parentCat in parents)
{
cats.Add(parentCat);
var subCats = await _FindAllSubCategories(context, parentCat.Id);
if(subCats.Count > 0)
{
cats.AddRange(subCats);
}
}
return cats;
}
private async Task<List<GanjoorCat>> _FindTargetCategories(RMuseumDbContext context, GanjoorCat startCat, int? endCatId)
{
if(endCatId == null || startCat.Id == endCatId)
{
List<GanjoorCat> cats = new List<GanjoorCat>();
cats.Add(startCat);
cats.AddRange(await _FindAllSubCategories(context, startCat.Id));
return cats;
}
else
{
return await _FindCategoryRanges(context, startCat, (int)endCatId);
}
}
/// <summary>
/// start counting
/// </summary>
/// <returns></returns>
public RServiceResult<bool> Count(int numberingId)
{
_backgroundTaskQueue.QueueBackgroundWorkItem
(
async token =>
{
using (RMuseumDbContext context = new RMuseumDbContext(new DbContextOptions<RMuseumDbContext>())) //this is long running job, so _context might be already been freed/collected by GC
{
LongRunningJobProgressServiceEF jobProgressServiceEF = new LongRunningJobProgressServiceEF(context);
var job = (await jobProgressServiceEF.NewJob("NumberingService::Count", "Query Cats")).Result;
try
{
var numbering = await context.GanjoorNumberings.Include(n => n.StartCat).Where(n => n.Id == numberingId).SingleOrDefaultAsync();
var cats = await _FindTargetCategories(context, numbering.StartCat, numbering.EndCatId);
await jobProgressServiceEF.UpdateJob(job.Id, 0, "Deleting Old Data");
var oldNumbers = await context.GanjoorVerseNumbers.Where(n => n.NumberingId == numberingId).ToListAsync();
context.GanjoorVerseNumbers.RemoveRange(oldNumbers);
await context.SaveChangesAsync();
await jobProgressServiceEF.UpdateJob(job.Id, 0, "Counting");
int number = 0;
int totalVerseCount = 0;
foreach (var cat in cats)
{
var poems = await context.GanjoorPoems.AsNoTracking().Where(p => p.CatId == cat.Id).OrderBy(p => p.Id).ToListAsync();
await jobProgressServiceEF.UpdateJob(job.Id, 0, $"Counting:: {cat.Title}");
foreach(var poem in poems)
{
totalVerseCount += await context.GanjoorVerses.Where(v => v.PoemId == poem.Id).CountAsync();
var verses = await context.GanjoorVerses.AsNoTracking()
.Where(v => v.PoemId == poem.Id && (v.VersePosition == VersePosition.Right || v.VersePosition == VersePosition.CenteredVerse1))
.OrderBy(v => v.VOrder)
.ToListAsync();
for (int coupletIndex = 0; coupletIndex < verses.Count; coupletIndex++)
{
number++;
GanjoorVerseNumber verseNumber = new GanjoorVerseNumber()
{
NumberingId = numberingId,
PoemId = poem.Id,
CoupletIndex = coupletIndex,
Number = number
};
context.GanjoorVerseNumbers.Add(verseNumber);
}
}
}
numbering.TotalCouplets = number;
numbering.TotalVerses = totalVerseCount;
numbering.LastCountingDate = DateTime.Now;
context.GanjoorNumberings.Update(numbering);
await context.SaveChangesAsync();
await jobProgressServiceEF.UpdateJob(job.Id, 100, "", true);
}
catch (Exception exp)
{
await jobProgressServiceEF.UpdateJob(job.Id, 100, "", false, exp.ToString());
}
}
}
);
return new RServiceResult<bool>(true);
}
/// <summary>
/// Database Context
/// </summary>
protected readonly RMuseumDbContext _context;
/// <summary>
/// Background Task Queue Instance
/// </summary>
protected readonly IBackgroundTaskQueue _backgroundTaskQueue;
/// <summary>
/// constructor
/// </summary>
/// <param name="context"></param>
public GanjoorNumberingService(RMuseumDbContext context)
/// <param name="backgroundTaskQueue"></param>
public GanjoorNumberingService(RMuseumDbContext context, IBackgroundTaskQueue backgroundTaskQueue)
{
_context = context;
_backgroundTaskQueue = backgroundTaskQueue;
}
}
}