private PerformanceEntity AddPerformanceEntity(IPerformanceData data, int locationId, int typeId) { try { LocationsEntity location = locationId != -1 ? _dbContext.PerformanceLocations.FirstOrDefault(l => l.Id == locationId) : new LocationsEntity { Name = data.Location }; PerformanceTypeEntity type = typeId != -1 ? _dbContext.PerformanceTypes.FirstOrDefault(t => t.Id == typeId) : new PerformanceTypeEntity { TypeName = data.Type }; PerformanceEntity performance = new PerformanceEntity { Name = data.Name, Location = location, Type = type, }; _dbContext.Performances.Add(performance); return(performance); } catch (Exception e) { Console.WriteLine($"AddPerformanceEntity DbException: {e.Message}"); throw; } }
public bool IsDataSuitable(IPerformanceData performance, IPerformanceFilter filter) { if (filter == null) { return(true); } if (filter.Locations != null && filter.Locations.Any() && !filter.Locations.Contains(performance.Location)) { return(false); } if (filter.PerformanceTypes != null && filter.PerformanceTypes.Any() && filter.PerformanceTypes.All(val => 0 != string.Compare(val, performance.Type, true))) { return(false); } if (filter.DaysOfWeek != null && filter.DaysOfWeek.Any() && !filter.DaysOfWeek.Contains(performance.DateTime.DayOfWeek)) { return(false); } return(true); }
public async Task <PlaybillEntity> AddPlaybill(IPerformanceData data) { try { int performanceId = GetPerformanceEntityId(data, out int location, out int type); PerformanceEntity performance = -1 == performanceId ? AddPerformanceEntity(data, location, type) : _dbContext.Performances .Include(p => p.Location) .Include(p => p.Type) .FirstOrDefault(p => p.Id == performanceId); var playBillEntry = new PlaybillEntity { Performance = performance, Url = data.Url, When = data.DateTime, Changes = new List <PlaybillChangeEntity> { new PlaybillChangeEntity { LastUpdate = DateTime.Now, MinPrice = data.MinPrice, ReasonOfChanges = (int)ReasonOfChanges.Creation, } } }; _dbContext.Playbill.Add(playBillEntry); _dbContext.Add(playBillEntry.Changes.First()); await _dbContext.SaveChangesAsync(); if (performance != null) { _dbContext.Entry(performance.Location).State = EntityState.Detached; _dbContext.Entry(performance.Type).State = EntityState.Detached; _dbContext.Entry(performance).State = EntityState.Detached; } return(playBillEntry); } catch (Exception ex) { Trace.TraceInformation($"AddPlaybill DbException {ex.Message} InnerException {ex.InnerException?.Message}"); } return(null); }
/// <summary> /// 最大最小和平均时延指标 /// </summary> /// <typeparam name="T">计数项类型</typeparam> /// <param name="data">性能数据</param> /// <param name="elapseProvider">从性能计数项中提取时延的方法</param> /// <returns></returns> public static PerformanceMetric[] Elapsed <T>(this IPerformanceData data, string name, Func <T, TimeSpan> elapseProvider) { var elapsed = data.GetEntries <T>().Select(item => elapseProvider(item).TotalMilliseconds).OrderBy(item => item); if (elapsed.Any()) { return(new[] { new PerformanceMetric($"{data.DataSource}.{name}", Aggregation.Max, elapsed.Last(), PerformanceMetricUnit.ms), new PerformanceMetric($"{data.DataSource}.{name}", Aggregation.Min, elapsed.First(), PerformanceMetricUnit.ms), new PerformanceMetric($"{data.DataSource}.{name}", Aggregation.Avg, elapsed.Average(), PerformanceMetricUnit.ms), }); } else { return(new PerformanceMetric[0]); } }
/// <summary> /// 得到指定百分比的基线值 /// </summary> /// <typeparam name="TEntry">计数项类型</typeparam> /// <typeparam name="TValue">计数值类型</typeparam> /// <param name="data">性能数据</param> /// <param name="baselines">要获取的基线值</param> /// <param name="valueProvider">计数值提供程序</param> /// <param name="comparer">用于比较两个计数值的比较器</param> /// <returns></returns> public static IReadOnlyDictionary <int, TValue> Baseline <TEntry, TValue>(this IPerformanceData data, int[] baselines, Func <TEntry, TValue> valueProvider, IComparer <TValue> comparer) { var values = data.GetEntries <TEntry>().Select(item => valueProvider(item)).OrderBy(item => item, comparer); var result = new Dictionary <int, TValue>(); foreach (var item in baselines) { if (item >= 100 || item <= 0) { throw new ArgumentOutOfRangeException("percent must greater than 0 and less than 100", nameof(item)); } var index = data.GetEntries <TEntry>().Count() * item / 100; result.Add(item, values.ElementAt(index)); } return(result); }
private int GetPerformanceEntityId(IPerformanceData data, out int locationId, out int typeId) { LocationsEntity l = _dbContext.PerformanceLocations.AsNoTracking() .FirstOrDefault(x => x.Name == data.Location); locationId = l?.Id ?? -1; PerformanceTypeEntity t = _dbContext.PerformanceTypes.AsNoTracking().FirstOrDefault(x => x.TypeName == data.Type); typeId = t?.Id ?? -1; if (l == null || t == null) { return(-1); } var performanceId = _dbContext.Performances.AsNoTracking() .FirstOrDefault(p => p.Location == l && p.Type == t && p.Name == data.Name)?.Id ?? -1; return(performanceId); }
private async Task ProcessData(IPerformanceData data, IPlaybillRepository playbillRepository) { if (data.DateTime < DateTime.Now) { return; } var playbillEntry = playbillRepository.Get(data); if (null == playbillEntry) { await playbillRepository.AddPlaybill(data); return; } var lastChange = playbillEntry.Changes .OrderByDescending(x => x.LastUpdate) .FirstOrDefault(); var compareResult = ComparePerformanceData(lastChange, data); if (compareResult == ReasonOfChanges.NoReason && lastChange != null) { lastChange.LastUpdate = DateTime.Now; await playbillRepository.Update(lastChange); return; } Trace.TraceInformation($"{data.Name} {data.DateTime:g} was changed. MinPrice is {data.MinPrice}"); await playbillRepository.AddChange(playbillEntry, new PlaybillChangeEntity { LastUpdate = DateTime.Now, MinPrice = data.MinPrice, ReasonOfChanges = (int)compareResult, }); }
public PlaybillEntity Get(IPerformanceData data) { try { var performanceId = GetPerformanceEntityId(data); if (-1 == performanceId) { return(null); } return(_dbContext.Playbill .Include(x => x.Changes) .Where(x => x.When == data.DateTime && x.PerformanceId == performanceId) .AsNoTracking() .FirstOrDefault()); } catch (Exception ex) { Trace.TraceInformation($"Get PlaybillEntity DbException {ex.Message} InnerException {ex.InnerException?.Message}"); } return(null); }
private ReasonOfChanges ComparePerformanceData(PlaybillChangeEntity lastChange, IPerformanceData freshData) { int freshMinPrice = freshData.MinPrice; if (lastChange == null) { return(freshMinPrice == 0 ? ReasonOfChanges.Creation : ReasonOfChanges.StartSales); } if (lastChange.MinPrice == 0) { return(freshMinPrice == 0 ? ReasonOfChanges.NoReason : ReasonOfChanges.StartSales); } if (lastChange.MinPrice > freshMinPrice) { return(ReasonOfChanges.PriceDecreased); } if (lastChange.MinPrice < freshMinPrice) { return(ReasonOfChanges.PriceIncreased); } return(ReasonOfChanges.NoReason); }
public bool Filter(IPerformanceData perfomance) { throw new NotImplementedException(); }
/// <summary> /// 计算平均每秒计数项 /// </summary> /// <typeparam name="T">计数项类型</typeparam> /// <param name="data">性能数据</param> /// <returns></returns> public static PerformanceMetric[] CountPerSecond <T>(this IPerformanceData data, string name) { return(new[] { new PerformanceMetric($"{data.DataSource}.{name}", Aggregation.Count, (double)data.GetEntries <T>().Count() / data.TimeRange.TimeSpan.TotalSeconds, PerformanceMetricUnit.rps) }); }
/// <summary> /// 统计计数项个数 /// </summary> /// <typeparam name="T">计数项类型</typeparam> /// <param name="data">性能数据</param> /// <returns></returns> public static PerformanceMetric[] Count <T>(this IPerformanceData data, string name) { return(new[] { new PerformanceMetric($"{data.DataSource}.{name}", Aggregation.Count, data.GetEntries <T>().Count(), PerformanceMetricUnit.pcs) }); }
private int GetPerformanceEntityId(IPerformanceData data) => GetPerformanceEntityId(data, out _, out _);