コード例 #1
0
ファイル: zvsContext.cs プロジェクト: lulzzz/zVirtualScenes
        public override async Task <int> SaveChangesAsync(CancellationToken cancellationToken)
        {
            //Limit Log Table Size
            const int maxLogSize         = 2000;
            var       addedLogEntryCount = ChangeTracker.Entries <LogEntry>().Count(p => p.State == EntityState.Added);

            if (addedLogEntryCount > 0)
            {
                if (addedLogEntryCount > maxLogSize)
                {
                    var numberToRemove = addedLogEntryCount - maxLogSize;
                    var doNotAdd       = ChangeTracker.Entries <LogEntry>()
                                         .Where(p => p.State == EntityState.Added)
                                         .OrderBy(o => o.Entity.Datetime).Take(numberToRemove);

                    foreach (var entry in doNotAdd)
                    {
                        entry.State = EntityState.Detached;
                    }
                }

                var currentLogEntryCount = await LogEntries.CountAsync(cancellationToken);

                var toRemove = (currentLogEntryCount + addedLogEntryCount) - maxLogSize;
                if (toRemove > 0)
                {
                    var toBeRemoved =
                        await LogEntries.OrderBy(o => o.Datetime).Take(toRemove).ToListAsync(cancellationToken);

                    LogEntries.RemoveRange(toBeRemoved);
                }
            }

            //Update Run Scene Command Scene Name upon Scene Name update
            var sceneIdsOfUpdatedNames = ChangeTracker.Entries <Scene>().Where(p => p.State == EntityState.Modified && p.Property("Name").IsModified).Select(o => o.Entity.Id.ToString(CultureInfo.InvariantCulture)).ToList();
            Expression <Func <IStoredCommand, bool> > sceneCmdPredicate = o => o.Command.UniqueIdentifier == "RUN_SCENE" && sceneIdsOfUpdatedNames.Contains(o.Argument);

            foreach (var cmd in await SceneStoredCommands.Where(sceneCmdPredicate).ToListAsync(cancellationToken))
            {
                await cmd.SetTargetObjectNameAsync(this);
            }

            foreach (var cmd in await DeviceValueTriggers.Where(sceneCmdPredicate).ToListAsync(cancellationToken))
            {
                await cmd.SetTargetObjectNameAsync(this);
            }

            foreach (var cmd in await ScheduledTasks.Where(sceneCmdPredicate).ToListAsync(cancellationToken))
            {
                await cmd.SetTargetObjectNameAsync(this);
            }

            //Update Activate Group Command Scene Name upon Group Name update
            var groupIdsOfUpdatedNames = ChangeTracker.Entries <Group>().Where(p => p.State == EntityState.Modified && p.Property("Name").IsModified).Select(o => o.Entity.Id.ToString(CultureInfo.InvariantCulture)).ToList();
            Expression <Func <IStoredCommand, bool> > groupPredicate = o => (o.Command.UniqueIdentifier == "GROUP_ON" || o.Command.UniqueIdentifier == "GROUP_OFF") && groupIdsOfUpdatedNames.Contains(o.Argument);

            foreach (var cmd in await SceneStoredCommands.Where(groupPredicate).ToListAsync(cancellationToken))
            {
                await cmd.SetTargetObjectNameAsync(this);
            }

            foreach (var cmd in await DeviceValueTriggers.Where(groupPredicate).ToListAsync(cancellationToken))
            {
                await cmd.SetTargetObjectNameAsync(this);
            }

            foreach (var cmd in await ScheduledTasks.Where(groupPredicate).ToListAsync(cancellationToken))
            {
                await cmd.SetTargetObjectNameAsync(this);
            }

            //Update cmd descriptions on JavaScriptCommand name changes
            var javescriptIdsOfUpdatedNameIds = ChangeTracker.Entries <JavaScriptCommand>().Where(p => p.State == EntityState.Modified && p.Property("Name").IsModified).Select(o => o.Entity.Id).ToList();
            Expression <Func <IStoredCommand, bool> > jsCmdPredicate = o => o.Command is JavaScriptCommand && javescriptIdsOfUpdatedNameIds.Contains(o.Command.Id);

            foreach (var cmd in await SceneStoredCommands.Where(jsCmdPredicate).ToListAsync(cancellationToken))
            {
                await cmd.SetTargetObjectNameAsync(this);
            }

            foreach (var cmd in await DeviceValueTriggers.Where(jsCmdPredicate).ToListAsync(cancellationToken))
            {
                await cmd.SetTargetObjectNameAsync(this);
            }

            foreach (var cmd in await ScheduledTasks.Where(jsCmdPredicate).ToListAsync(cancellationToken))
            {
                await cmd.SetTargetObjectNameAsync(this);
            }

            //Update trigger descriptions on device value name changes
            var deviceValueIdsOfUpdatedNames = ChangeTracker.Entries <DeviceValue>().Where(p => p.State == EntityState.Modified && p.Property("Name").IsModified).Select(o => o.Entity.Id).ToList();
            var triggers = await DeviceValueTriggers.Include(o => o.DeviceValue).Include(o => o.DeviceValue.Device).Where(o => deviceValueIdsOfUpdatedNames.Contains(o.DeviceValue.Id)).ToListAsync(cancellationToken);

            foreach (var trigger in triggers)
            {
                trigger.SetDescription();
            }

            //Update commands on device name changes
            var deviceIdsOfUpdatedNames    = ChangeTracker.Entries <Device>().Where(p => p.State == EntityState.Modified && (p.Property("Name").IsModified || p.Property("Location").IsModified)).Select(o => o.Entity.Id).ToList();
            var deviceIdsStrOfUpdatedNames = deviceIdsOfUpdatedNames.Select(o => o.ToString());
            var deviceTriggers             = await DeviceValueTriggers.Include(o => o.DeviceValue).Include(o => o.DeviceValue.Device).Where(o => deviceIdsOfUpdatedNames.Contains(o.DeviceValue.DeviceId)).ToListAsync(cancellationToken);

            foreach (var trigger in deviceTriggers)
            {
                trigger.SetDescription();
            }

            //Update repoll commands
            Expression <Func <IStoredCommand, bool> > repollCmdPredicate = o => o.Command.UniqueIdentifier == "REPOLL_ME" && deviceIdsStrOfUpdatedNames.Contains(o.Argument);

            foreach (var cmd in await SceneStoredCommands.Where(repollCmdPredicate).ToListAsync(cancellationToken))
            {
                await cmd.SetTargetObjectNameAsync(this);
            }

            foreach (var cmd in await DeviceValueTriggers.Where(repollCmdPredicate).ToListAsync(cancellationToken))
            {
                await cmd.SetTargetObjectNameAsync(this);
            }

            foreach (var cmd in await ScheduledTasks.Where(repollCmdPredicate).ToListAsync(cancellationToken))
            {
                await cmd.SetTargetObjectNameAsync(this);
            }

            Expression <Func <IStoredCommand, bool> > deviceTypeCmdPredicate = o => o.Command is DeviceTypeCommand && deviceIdsStrOfUpdatedNames.Contains(o.Argument2);

            foreach (var cmd in await SceneStoredCommands.Where(deviceTypeCmdPredicate).ToListAsync(cancellationToken))
            {
                await cmd.SetTargetObjectNameAsync(this);
            }

            foreach (var cmd in await DeviceValueTriggers.Where(deviceTypeCmdPredicate).ToListAsync(cancellationToken))
            {
                await cmd.SetTargetObjectNameAsync(this);
            }

            foreach (var cmd in await ScheduledTasks.Where(deviceTypeCmdPredicate).ToListAsync(cancellationToken))
            {
                await cmd.SetTargetObjectNameAsync(this);
            }

            var deviceCommandIds = await DeviceCommands.Where(o => deviceIdsOfUpdatedNames.Contains(o.DeviceId)).Select(o => o.Id).ToListAsync(cancellationToken);

            Expression <Func <IStoredCommand, bool> > deviceCmdPredicate = o => o.Command is DeviceCommand && deviceCommandIds.Contains(o.Command.Id);

            foreach (var cmd in await SceneStoredCommands.Where(deviceCmdPredicate).ToListAsync(cancellationToken))
            {
                await cmd.SetTargetObjectNameAsync(this);
            }

            foreach (var cmd in await DeviceValueTriggers.Where(deviceCmdPredicate).ToListAsync(cancellationToken))
            {
                await cmd.SetTargetObjectNameAsync(this);
            }

            foreach (var cmd in await ScheduledTasks.Where(deviceCmdPredicate).ToListAsync(cancellationToken))
            {
                await cmd.SetTargetObjectNameAsync(this);
            }

            //Automatically store history when a device value is changed.
            var history =
                ChangeTracker.Entries <DeviceValue>()
                .Where(p => p.State == EntityState.Modified && p.Property("Value").IsModified)
                .Select(
                    o => new DeviceValueHistory
            {
                DeviceValueId = o.Entity.Id,
                Value         = o.Entity.Value
            }).ToList();

            DeviceValueHistories.AddRange(history);
            return(await base.SaveChangesAsync(cancellationToken));
        }