private IndiagramForDevice ToIndiagramForDevice(Indiagram indiagram, IndiagramInfo info, IndiagramState state)
 {
     return new IndiagramForDevice
     {
         Id = indiagram.Id,
         Version = info.Version,
         ImageHash = info.ImageHash,
         IsCategory = info.IsCategory,
         ParentId = info.ParentId,
         SoundHash = info.SoundHash,
         Text = info.Text,
         Position = info.Position,
         IsEnabled = state == null || state.IsEnabled,
         ImageFile = info.ImagePath,
         SoundFile = info.SoundPath
     };
 }
        private IndiagramForDevice ToIndiagramForDevice(Device device, Indiagram indiagram, IndiagramInfo info)
        {
            IndiagramState state = info.States.FirstOrDefault(s => s.DeviceId == device.Id);

            return ToIndiagramForDevice(indiagram, info, state);
        }
        private IndiagramForDevice ToIndiagramForDevice(Device device, Indiagram indiagram, long version)
        {
            IndiagramInfo info = indiagram.Infos.OrderByDescending(item => item.Version).FirstOrDefault(item => item.Version <= version);
            if (info == null)
            {
                return null;
            }

            return ToIndiagramForDevice(device, indiagram, info);
        }
        private IndiagramForDevice ToIndiagramForDevice(Device device, Indiagram indiagram, bool allowOpenedVersion)
        {
            IndiagramInfo info = indiagram.LastIndiagramInfo;
            if (info == null)
            {
                return null;
            }

            if (!allowOpenedVersion && IsVersionOpen(device.UserId, info.Version))
            {
                info = indiagram.Infos.OrderByDescending(item => item.Version).FirstOrDefault(item => !IsVersionOpen(device.UserId, item.Version));

                if (info == null)
                {
                    return null;
                }
            }

            return ToIndiagramForDevice(device, indiagram, info);
        }
        private IndiagramInfo CreateIndiagramInfo(Indiagram indiagram, IndiagramInfo old, long version)
        {
            IndiagramInfo info = _context.Set<IndiagramInfo>().Add(new IndiagramInfo
            {
                IndiagramId = indiagram.Id,
                Version = version,
                ParentId = old.ParentId,
                Position = old.Position,
                Text = old.Text,
                SoundPath = old.SoundPath,
                SoundHash = old.SoundHash,
                ImagePath = old.ImagePath,
                ImageHash = old.ImageHash,
                IsCategory = old.IsCategory,
            });
            DbSet<IndiagramState> stateSet = _context.Set<IndiagramState>();

            info.States = old.States.Select(x => stateSet.Add(
                new IndiagramState
                {
                    DeviceId = x.DeviceId,
                    IndiagramInfoId = info.Id,
                    IsEnabled = x.IsEnabled
                })).ToList();

            if (indiagram.LastIndiagramInfoId == null || indiagram.LastIndiagramInfo.Version < version)
            {
                indiagram.LastIndiagramInfoId = info.Id;
            }

            _context.SaveChanges();
            return info;
        }
        private IndiagramInfo CreateIndiagramInfo(Indiagram indiagram, long version)
        {
            IndiagramInfo info = indiagram.Infos.OrderByDescending(x => x.Version).FirstOrDefault(x => x.Version <= version);
            if (info == null)
            {
                // no version available
                return null;
            }

            if (info.Version == version)
            {
                return info;
            }

            // create IndiagramInfo based on last version available
            return CreateIndiagramInfo(indiagram, info, version);
        }