Fix WitsRecordRepository.SaveDataAsync(). Add some milliseconds to duplicated records.

This commit is contained in:
ngfrolov 2022-10-25 17:23:01 +05:00
parent 33dd020b7e
commit 3f5d3cf865
2 changed files with 57 additions and 9 deletions

View File

@ -69,6 +69,14 @@ namespace AsbCloudDb
return database.ExecuteSqlRawAsync(query, token);
}
public static Task<int> ExecInsertOrIgnoreAsync<T>(this Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade database, DbSet<T> dbSet, IEnumerable<T> items, CancellationToken token)
where T : class
{
var factory = GetQueryStringFactory(dbSet);
var query = factory.MakeInsertOrIgnoreSql(items);
return database.ExecuteSqlRawAsync(query, token);
}
public static Task<int> ExecInsertAsync<T>(this Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade database, DbSet<T> dbSet, IEnumerable<T> items, CancellationToken token)
where T : class
{
@ -162,6 +170,14 @@ namespace AsbCloudDb
conflictBody = $" ON CONFLICT {pk} DO UPDATE SET {excludedUpdateSet};";
}
public string MakeInsertOrIgnoreSql(IEnumerable<T> items)
{
var builder = new StringBuilder(insertHeader, 7);
BuildRows(builder, items);
builder.Append(" ON CONFLICT DO NOTHING;");
return builder.ToString();
}
public string MakeInsertOrUpdateSql(IEnumerable<T> items)
{
var builder = new StringBuilder(insertHeader, 7);

View File

@ -12,9 +12,10 @@ using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Repository
{
public class WitsRecordRepository<TDto, TEntity> : IWitsRecordRepository<TDto>
where TEntity : class, ITelemetryData
where TEntity : AsbCloudDb.Model.WITS.RecordBase, ITelemetryData
where TDto : AsbCloudApp.Data.ITelemetryData
{
private static Random random = new Random((int)(DateTime.Now.Ticks % 0xFFFFFFFF));
private readonly DbSet<TEntity> dbset;
private readonly IAsbCloudDbContext db;
private readonly ITelemetryService telemetryService;
@ -78,29 +79,60 @@ namespace AsbCloudInfrastructure.Repository
var dateMin = entities.Min(e => e.DateTime);
var dateMax = entities.Max(e => e.DateTime);
var existingEntities = await dbset
var existingEntities = await db.Set<AsbCloudDb.Model.WITS.RecordBase>()
.Where(e => e.IdTelemetry == idTelemetry)
.Where(e => e.DateTime >= dateMin && e.DateTime <= dateMax)
.Select(e => new { e.DateTime, e.IdTelemetry})
.Select(e => e.DateTime)
.OrderBy(d => d)
.ToArrayAsync(token);
foreach (var entity in entities)
{
if (existingEntities.Any(e=>e.IdTelemetry == entity.IdTelemetry && e.DateTime == entity.DateTime))
dbset.Update(entity);
else
if (!existingEntities.Any(e => e.DateTime == entity.DateTime))
{
dbset.Add(entity);
}
else
{
var dt = entity.DateTime;
entity.DateTime = new DateTimeOffset(
dt.Year,
dt.Month,
dt.Day,
dt.Hour,
dt.Minute,
dt.Second,
(dt.Millisecond + random.Next(1, 283)) % 1000,
dt.Offset);
dbset.Add(entity);
}
}
await db.SaveChangesAsync(token);
}
private static short GetRecId(TDto dto)
{
var recid = dto switch
{
AsbCloudApp.Data.WITS.Record1Dto _ => 1,
AsbCloudApp.Data.WITS.Record7Dto _ => 7,
AsbCloudApp.Data.WITS.Record8Dto _ => 8,
AsbCloudApp.Data.WITS.Record50Dto _ => 50,
AsbCloudApp.Data.WITS.Record60Dto _ => 60,
AsbCloudApp.Data.WITS.Record61Dto _ => 61,
_ => 0,
};
return (short)recid;
}
private static TEntity Convert(TDto dto, int idTelemetry, double timezoneHours)
{
if (dto is null)
return null;
var entity = dto.Adapt<TEntity>();
entity.Recid = GetRecId(dto);
entity.IdTelemetry = idTelemetry;
entity.DateTime = dto.DateTime.ToUtcDateTimeOffset(timezoneHours);
return entity;