示例#1
0
        /// <summary>
        /// Saves the specified egm metrics.
        /// </summary>
        /// <param name="egmMetrics">The egm metrics.</param>
        public void Save(ICollection <EgmMetric> egmMetrics)
        {
            using (var context = new HmsDbContext())
            {
                //context.Database.Log = Console.Write;

                foreach (var egmMetric in egmMetrics)
                {
                    if (!context.EgmMetrics.Any(metric => metric.Id == egmMetric.Id))
                    {
                        // no matching PK for this EgmMetric in database,
                        // thus we create new entity and add it to db
                        DaoUtilities.SaveCreatedEntity(context, context.EgmMetrics, egmMetric,
                                                       SetNewEntityState, false);
                    }
                    else
                    {
                        // matching PK found, thus we update state of existing EgmMetric entity
                        DaoUtilities.SaveUpdatedEntity(context, context.EgmMetrics, egmMetric,
                                                       UpdateExistingEntityState, false);
                    }
                }

                DaoUtilities.SaveToDbWithRetry(context, DaoUtilities.SaveType.UpdateExistingEntity,
                                               ResolveEntityUpdateConflict);
            }
        }
        /// <summary>
        /// Saves the specified composite egm meter datas.
        /// </summary>
        /// <param name="compositeEgmMeterDatas">The composite egm meter datas.</param>
        public void Save(ICollection <CompositeEgmMeterData> compositeEgmMeterDatas)
        {
            using (var context = new HmsDbContext())
            {
                //context.Database.Log = Console.Write;

                foreach (var compositeEgmMeterData in compositeEgmMeterDatas)
                {
                    if (!context.CompositeEgmMeterDatas.Any(cemd => cemd.Id == compositeEgmMeterData.Id))
                    {
                        // no matching PK for this CompositeEgmMeterData in database,
                        // thus we create new entity and add it to db
                        DaoUtilities.SaveCreatedEntity(context, context.CompositeEgmMeterDatas, compositeEgmMeterData,
                                                       SetNewEntityState, false);
                    }
                    else
                    {
                        // matching PK found, thus we update state of existing CompositeEgmMeterData entity
                        DaoUtilities.SaveUpdatedEntity(context, context.CompositeEgmMeterDatas, compositeEgmMeterData,
                                                       UpdateExistingEntityState, false);
                    }
                }

                DaoUtilities.SaveToDbWithRetry(context, DaoUtilities.SaveType.UpdateExistingEntity,
                                               ResolveEntityUpdateConflict);
            }
        }
示例#3
0
 /// <summary>
 /// Cleans EgmMetric Entities older than specified date-time.
 /// </summary>
 /// <param name="oldDateTime">The old date time.</param>
 public void CleanOlderThan(DateTime oldDateTime)
 {
     using (var context = new HmsDbContext())
     {
         context.EgmMetrics.RemoveRange(
             context.EgmMetrics.Where(
                 mr => mr.ReportedAt != DaoUtilities.UnsentData && mr.ReportedAt < oldDateTime));
         DaoUtilities.SaveToDbWithRetry(context, DaoUtilities.SaveType.DeleteExistingEntity,
                                        ResolveEntityUpdateConflict);
     }
 }
        /// <summary>
        /// Deletes the specified composite egm meter data.
        /// </summary>
        /// <param name="compositeEgmMeterData">The composite egm meter data.</param>
        public void Delete(CompositeEgmMeterData compositeEgmMeterData)
        {
            using (var context = new HmsDbContext())
            {
                if (!context.CompositeEgmMeterDatas.Any(cemd => cemd.Id == compositeEgmMeterData.Id))
                {
                    return;
                }

                // matching PK found, thus we proceed with Delete
                DaoUtilities.DeleteEntity(context, context.CompositeEgmMeterDatas, compositeEgmMeterData);
            }
        }
示例#5
0
        /// <summary>
        /// Deletes the specified EgmMetric entity.
        /// </summary>
        /// <param name="egmMetric">The EgmMetric entity to delete.</param>
        public void Delete(EgmMetric egmMetric)
        {
            using (var context = new HmsDbContext())
            {
                if (!context.EgmMetrics.Any(mr => mr.Id == egmMetric.Id))
                {
                    return;
                }

                // matching PK found, thus we proceed with Delete
                DaoUtilities.DeleteEntity(context, context.EgmMetrics, egmMetric);
            }
        }
示例#6
0
        /// <summary>
        /// Deletes the specified EgmVersion entity.
        /// </summary>
        /// <param name="egmVersion">The EgmVersion entity to delete.</param>
        public void Delete(EgmVersion egmVersion)
        {
            using (var context = new HmsDbContext())
            {
                if (!context.EgmVersions.Any(v => v.Id == egmVersion.Id))
                {
                    return;
                }

                // matching PK found, thus we proceed with Delete
                DaoUtilities.DeleteEntity(context, context.EgmVersions, egmVersion);
            }
        }
        /// <summary>
        /// Deletes the specified egm windows event entity.
        /// </summary>
        /// <param name="egmWindowsEvent">The egm windows event entity.</param>
        public void Delete(EgmWindowsEvent egmWindowsEvent)
        {
            using (var context = new HmsDbContext())
            {
                if (!context.EgmWindowsEvents.Any(winEvt => winEvt.Id == egmWindowsEvent.Id))
                {
                    return;
                }

                // matching PK found, thus we proceed with Delete
                DaoUtilities.DeleteEntity(context, context.EgmWindowsEvents, egmWindowsEvent);
            }
        }
示例#8
0
        /// <summary>
        /// Updates the state of the existing entity.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityEntry">The entity entry.</param>
        /// <param name="egmMetric">The egm metric.</param>
        private static void UpdateExistingEntityState(HmsDbContext context, DbEntityEntry entityEntry,
                                                      EgmMetric egmMetric)
        {
            var metricEntity = (EgmMetric)entityEntry.Entity;

            if (!metricEntity.SentAt.Equals(egmMetric.SentAt))
            {
                metricEntity.SentAt = egmMetric.SentAt;
            }

            if (!metricEntity.ReportGuid.Equals(egmMetric.ReportGuid))
            {
                metricEntity.ReportGuid = egmMetric.ReportGuid;
            }

            DaoUtilities.UpdateVersion(context, entityEntry);
        }
        /// <summary>
        /// Updates the state of the existing entity.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityEntry">The entity entry.</param>
        /// <param name="egmWindowsEvent">The egm windows event entity.</param>
        private static void UpdateExistingEntityState(HmsDbContext context, DbEntityEntry entityEntry,
                                                      EgmWindowsEvent egmWindowsEvent)
        {
            var winEvtEntity = (EgmWindowsEvent)entityEntry.Entity;

            if (!winEvtEntity.SentAt.Equals(egmWindowsEvent.SentAt))
            {
                winEvtEntity.SentAt = egmWindowsEvent.SentAt;
            }

            if (!winEvtEntity.ReportGuid.Equals(egmWindowsEvent.ReportGuid))
            {
                winEvtEntity.ReportGuid = egmWindowsEvent.ReportGuid;
            }

            DaoUtilities.UpdateVersion(context, entityEntry);
        }
示例#10
0
 /// <summary>
 /// Resolves the entity update conflict.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="entityEntry">The entity entry.</param>
 private static void ResolveEntityUpdateConflict(HmsDbContext context, DbEntityEntry entityEntry)
 {
     ///////////////////////////////////////////////////////////////////////////
     // This should never occur for EgmMetric entities
     // because we simply add records to the db table when we receive
     // them from the HMS EGM Client message (HMS Onsite Service) or the HMS Onsite
     // Service (HMS Cloud Service). We do update the records on the
     // HMS Onsite Service when we package them up and send them to
     // the HMS Cloud Service (ReportGuid and SentAt fields are updated)
     // but in a single-threaded way and only after having created the
     // initial record.
     //
     // We will use the "first in wins" resolution approach, but this ought
     // never be invoked.
     //////////////////////////////////////////////////////////////////////////
     entityEntry.Reload();
     DaoUtilities.UpdateVersion(context, entityEntry);
 }
示例#11
0
        /// <summary>
        /// Saves the specified EgmMetric.
        /// </summary>
        /// <param name="egmMetric">The EgmMetric to save.</param>
        public void Save(EgmMetric egmMetric)
        {
            using (var context = new HmsDbContext())
            {
                //context.Database.Log = Console.Write;

                if (!context.EgmMetrics.Any(metric => metric.Id == egmMetric.Id))
                {
                    // no matching PK for this EgmMetric in database,
                    // thus we create new entity and add it to db
                    DaoUtilities.SaveCreatedEntity(context, context.EgmMetrics, egmMetric, SetNewEntityState);
                }
                else
                {
                    // matching PK found, thus we update state of existing EgmMetric entity
                    DaoUtilities.SaveUpdatedEntity(context, context.EgmMetrics, egmMetric, UpdateExistingEntityState);
                }
            }
        }
        /// <summary>
        /// Saves the specified composite EGM meter data.
        /// </summary>
        /// <param name="compositeEgmMeterData">The composite EGM meter data.</param>
        public void Save(CompositeEgmMeterData compositeEgmMeterData)
        {
            using (var context = new HmsDbContext())
            {
                //context.Database.Log = Console.Write;

                if (!context.CompositeEgmMeterDatas.Any(cemd => cemd.Id == compositeEgmMeterData.Id))
                {
                    // no matching PK for this CompositeEgmMeterData in database,
                    // thus we create new entity and add it to db
                    DaoUtilities.SaveCreatedEntity(context, context.CompositeEgmMeterDatas, compositeEgmMeterData,
                                                   SetNewEntityState);
                }
                else
                {
                    // matching PK found, thus we update state of existing CompositeEgmMeterData entity
                    DaoUtilities.SaveUpdatedEntity(context, context.CompositeEgmMeterDatas, compositeEgmMeterData,
                                                   UpdateExistingEntityState);
                }
            }
        }
        /// <summary>
        /// Resolves the entity update conflict.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityEntry">The entity entry.</param>
        private static void ResolveEntityUpdateConflict(HmsDbContext context, DbEntityEntry entityEntry)
        {
            ///////////////////////////////////////////////////////////////////////////
            // There is potential for DbConcurrencyUpdate optimistic locking conflicts
            // with CompositeEgmMeterData entities.
            //
            // Specifically, when multiple threads are consuming incoming meter reading
            // data on the HMS Cloud Service, there is the potential for more than one
            // such thread to have meter readings with the same EgmCompositeKey.
            //
            // Thus, we need to sort out such potential conflicts here.
            //////////////////////////////////////////////////////////////////////////
            var currentValues  = entityEntry.CurrentValues;
            var originalValues = entityEntry.OriginalValues;

            entityEntry.Reload();
            var dbValues = entityEntry.CurrentValues;

            var currentUpdates = new List <string>();
            var dbUpdates      = new List <string>();

            var mutableMeters = new List <string>
            {
                nameof(CompositeEgmMeterData.CoinIn),
                nameof(CompositeEgmMeterData.CoinOut),
                nameof(CompositeEgmMeterData.BillDrop),
                nameof(CompositeEgmMeterData.GamesPlayed),
                nameof(CompositeEgmMeterData.GamesLost),
                nameof(CompositeEgmMeterData.GamesWon),
                nameof(CompositeEgmMeterData.Handpay),
                nameof(CompositeEgmMeterData.Jackpot),
                nameof(CompositeEgmMeterData.MeteredAttendantPaidProgressive),
                nameof(CompositeEgmMeterData.MeteredMachinePaidProgressive),
                nameof(CompositeEgmMeterData.TicketDrop),
                nameof(CompositeEgmMeterData.TicketOut)
            };

            // Look for updates to meters (relative to original values) in both
            // current changes and conflicting db updates
            foreach (var meter in mutableMeters)
            {
                if (currentValues.GetValue <long>(meter) != originalValues.GetValue <long>(meter))
                {
                    currentUpdates.Add(meter);
                }

                if (dbValues.GetValue <long>(meter) != originalValues.GetValue <long>(meter))
                {
                    dbUpdates.Add(meter);
                }
            }

            // Check if there are meters which were updated in both our current updates
            // and the conflicting db updates.
            foreach (var commonMeter in currentUpdates.Intersect(dbUpdates))
            {
                // since the mutable meters can only increase in value,
                // we take the larger value as winner
                var currentMeterValue = currentValues.GetValue <long>(commonMeter);
                var dbMeterValue      = dbValues.GetValue <long>(commonMeter);
                entityEntry.CurrentValues[commonMeter] = currentMeterValue > dbMeterValue
                    ? currentMeterValue
                    : dbMeterValue;

                currentUpdates.Remove(commonMeter);
                dbUpdates.Remove(commonMeter);
            }

            // Take any current updates and apply to entity
            foreach (var meter in currentUpdates)
            {
                entityEntry.CurrentValues[meter] = currentValues.GetValue <long>(meter);
            }

            // Finally, we update the dependent meters (SlotRevenue and AverageBet)
            var coinIn      = entityEntry.CurrentValues.GetValue <long>(nameof(CompositeEgmMeterData.CoinIn));
            var coinOut     = entityEntry.CurrentValues.GetValue <long>(nameof(CompositeEgmMeterData.CoinOut));
            var gamesPlayed = entityEntry.CurrentValues.GetValue <long>(nameof(CompositeEgmMeterData.GamesPlayed));
            var jackpot     = entityEntry.CurrentValues.GetValue <long>(nameof(CompositeEgmMeterData.Jackpot));

            if (CompositeEgmMeterData.MeterNotRecordedL != coinIn &&
                CompositeEgmMeterData.MeterNotRecordedL != gamesPlayed && 0 < gamesPlayed)
            {
                entityEntry.CurrentValues[nameof(CompositeEgmMeterData.AverageBet)] = (decimal)coinIn / gamesPlayed;
            }

            if (CompositeEgmMeterData.MeterNotRecordedL != coinIn &&
                CompositeEgmMeterData.MeterNotRecordedL != coinOut &&
                CompositeEgmMeterData.MeterNotRecordedL != jackpot)
            {
                entityEntry.CurrentValues[nameof(CompositeEgmMeterData.SlotRevenue)] = coinIn - coinOut - jackpot;
            }

            DaoUtilities.UpdateVersion(context, entityEntry);
        }
 /// <summary>
 /// Updates the state of the existing entity.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="entityEntry">The entity entry.</param>
 /// <param name="compositeEgmMeterData">The composite egm meter data.</param>
 private static void UpdateExistingEntityState(HmsDbContext context, DbEntityEntry entityEntry,
                                               ICompositeEgmMeterData compositeEgmMeterData)
 {
     entityEntry.CurrentValues.SetValues(compositeEgmMeterData);
     DaoUtilities.UpdateVersion(context, entityEntry);
 }