private async Task InnitDB(CancellationToken cancellationToken) { var context = new TagLogContext(FileName); var storedInfo = await context.TagLogInfo.ToListAsync(cancellationToken).ConfigureAwait(false); foreach (var cfg in Configs) { var storedTagLogInfo = context.TagLogInfo.FirstOrDefault(e => e.FacilityAccessName == cfg.TagLogInfo.FacilityAccessName && e.DeviceName == cfg.TagLogInfo.DeviceName && e.TagName == cfg.TagLogInfo.TagName); if (storedTagLogInfo == default) { storedTagLogInfo = new TagLogInfo { FacilityAccessName = cfg.TagLogInfo.FacilityAccessName, DeviceName = cfg.TagLogInfo.DeviceName, TagName = cfg.TagLogInfo.TagName, }; context.TagLogInfo.Add(storedTagLogInfo); storedInfo.Add(storedTagLogInfo); } cfg.TagLogInfo = storedTagLogInfo; } await context.SaveChangesAsync(cancellationToken).ConfigureAwait(false); context.Dispose(); }
/// <summary> /// Получить архивные данные. /// </summary> /// <param name="ids">Идентификаторы параметров</param> /// <param name="tBegin">Время начала для выборки</param> /// <param name="tEnd">время окончания выборки</param> /// <returns></returns> public async Task <IEnumerable <TagLogData> > GetData(TagLogFilter filter) { var context = new TagLogContext(FileName); var query = from a in context.TagLogData select a; var offset = 0; var count = 200; #pragma warning disable CA1307 // Укажите StringComparison if (filter != default) { if (filter.TBegin != long.MinValue) { query = query.Where(a => a.TimeStamp >= filter.TBegin); } if (filter.TEnd != long.MaxValue) { query = query.Where(a => a.TimeStamp <= filter.TEnd); } if (filter.InfoIds != default) { query = query.Where(a => filter.InfoIds.Contains(a.TagLogInfo.Id)); } if (filter.FacilityAccessName != default) { query = query.Where(a => a.TagLogInfo.FacilityAccessName == filter.FacilityAccessName); } if (filter.DeviceName != default) { query = query.Where(a => a.TagLogInfo.DeviceName == filter.DeviceName); } if (filter.TagNames != default) { query = query.Where(a => filter.TagNames.Contains(a.TagLogInfo.TagName)); } if (filter.Count != 0) { offset = filter.Offset; count = filter.Count; } } #pragma warning restore CA1307 // Укажите StringComparison var result = await query.Skip(offset).Take(count).ToListAsync().ConfigureAwait(false); context.Dispose(); return(result); }
private async Task SaveAsync(Queue <TagLogData> cache, CancellationToken cancellationToken) { if ((cache?.Count ?? 0) == 0) { return; } var context = new TagLogContext(FileName); /* // Код как оно должно работать * context.TagLogData.AddRange(cache); * await context.SaveChangesAsync(cancellationToken).ConfigureAwait(false); */ // ########## Начало костыля // TODO: при новых версиях EF Core (> 3.0.1) пробовать убрать этот костыль const int maxItemsInInsert = 128; while (cache.Count > 0) { var len = cache.Count > maxItemsInInsert ? maxItemsInInsert : cache.Count; var sql = "INSERT INTO TagLogData (\"TimeStamp\", \"TagLogInfoId\", \"Value\") VALUES "; for (var i = 0; i < len; i++) { var item = cache.Dequeue(); sql += $"({item.TimeStamp}, {item.TagLogInfoId}, {item.Value})" + ","; } sql = sql.Trim().Trim(',') + ';'; await context.Database.ExecuteSqlRawAsync(sql).ConfigureAwait(false); } // ########## Конец костыля if (nextMaintain < DateTime.Now) { nextMaintain = DateTime.Now + MinMaintainPeriod; var count = await context.TagLogData.LongCountAsync(cancellationToken).ConfigureAwait(false); if (count > StoreItemsCount) { var countToRemove = count - StoreItemsCount + DeltaRecordsCount; int ctr = countToRemove <0 ? 0 : countToRemove> int.MaxValue ? int.MaxValue : (int)countToRemove; var itemsToRemove = context.TagLogData.Take(ctr); context.TagLogData.RemoveRange(itemsToRemove); await context.SaveChangesAsync(cancellationToken).ConfigureAwait(false); await context.Database.ExecuteSqlRawAsync("VACUUM ;").ConfigureAwait(false); nextMaintain = DateTime.Now + 4 * MinMaintainPeriod; // после такого можно чуть подольше не проверять:) } } context.Dispose(); }