private ShardSetConfig MakeShardSetConfig(Models.ShardSetConfig shardSetConfigModel)
        {
            var shardSetConfig =
                new ShardSetConfig
            {
                ShardSetConfigID     = shardSetConfigModel.ShardSetConfigID,
                ShardSetID           = shardSetConfigModel.ShardSetID,
                AllowDeployments     = shardSetConfigModel.AllowDeployment,
                CurrentShardCount    = shardSetConfigModel.ShardMap.RangeShards.Count(),
                MaxShardCount        = shardSetConfigModel.MaxShardCount,
                MaxShardSizeMb       = shardSetConfigModel.MaxShardSizeMB,
                MaxShardletsPerShard = shardSetConfigModel.MaxShardletsPerShard,
                MinShardSizeMb       = shardSetConfigModel.MinShardSizeMB,
                TargetShardCount     = shardSetConfigModel.TargetShardCount,
                Version      = shardSetConfigModel.Version,
                ShardSetName = shardSetConfigModel.ShardSet.Name,
                CurrentPublishedShardMapID = shardSetConfigModel.ShardSet.CurrentShardMapID,
                ShardMap = new ShardMap
                {
                    ShardMapID = shardSetConfigModel.ShardMapID,
                    Shards     =
                        shardSetConfigModel.ShardMap.RangeShards
                        .Select(s =>
                                new RangeShard
                    {
                        ServerInstanceName  = s.Database.Server.ServerName,
                        Catalog             = s.Database.DatabaseName,
                        HighDistributionKey = s.RangeHighValue,
                        LowDistributionKey  = s.RangeLowValue,
                        ShardID             = s.ShardID
                    })
                        .ToList()
                },
                Shards = shardSetConfigModel.ShardSet.Shards
                         .Select(x =>
                                 new Shard
                {
                    Catalog            = x.Database.DatabaseName,
                    ServerInstanceName = x.Database.Server.ServerName,
                    Description        = x.Description,
                    PointerShardID     = x.ShardID
                })
                         .ToList(),
                Servers = shardSetConfigModel.ShardSet.Servers
                          .Select(x =>
                                  new Server
                {
                    ServerID           = x.ServerID,
                    ServerInstanceName = x.ServerName,
                    MaxShardsAllowed   = x.MaxShardsAllowed,
                    AvailableShards    = x.MaxShardsAllowed - x.Databases.Count
                                         //TODO : Change to databases that are deployed or planned.. not all databases in history
                })
                          .ToList(),
                ShardSetConfigSettings = shardSetConfigModel.ShardSetConfigSettings
                                         .Select(x =>
                                                 new DataElasticity.Models.ShardSetConfigSetting
                {
                    ShardSetConfigSettingID = x.ShardSetConfigSettingID,
                    ShardSetConfigID        = x.ShardSetConfigID,
                    SettingKey   = x.SettingKey,
                    SettingValue = x.SettingValue
                })
                                         .ToList(),
            };

            return(shardSetConfig);
        }
        public ShardSetConfig AddShardSetConfig(
            ShardSetConfig shardSetConfig)
        {
            using (var context = GetConnection(ConnectionString))
            {
                using (var scope = new TransactionScope())
                {
                    ShardSet shardSet;

                    // Locate the associated shard set either by the key or the shard set name
                    // If it does not exist, create and save it.

                    // Check to see if they gave us a ShardSetID
                    if (shardSetConfig.ShardSetID == -1)
                    {
                        // Lets try to look it up by Name
                        shardSet =
                            context.ShardSets.FirstOrDefault(x => x.Name == shardSetConfig.ShardSetName);

                        //If it doesn't exist create it.
                        if (shardSet == null)
                        {
                            shardSet =
                                new ShardSet
                            {
                                Name = shardSetConfig.ShardSetName
                            };

                            context.ShardSets.Add(shardSet);
                        }
                    }
                    else
                    {
                        shardSet =
                            context.ShardSets.FirstOrDefault(
                                x => x.ShardSetID == shardSetConfig.ShardSetID);

                        if (shardSet == null)
                        {
                            throw new InvalidOperationException(string.Format("Shard Set ID {0} does not exist",
                                                                              shardSetConfig.ShardSetID));
                        }
                    }


                    // if the configuration is being saved with a new Id, record it on the config table
                    if (shardSetConfig.CurrentPublishedShardMapID.HasValue)
                    {
                        shardSet.CurrentShardMapID = shardSetConfig.CurrentPublishedShardMapID;
                    }

                    // Nuke the server list because we are going to reload it from the configuration
                    shardSet.Servers.Clear();

                    //Now read the servers
                    foreach (var server in shardSetConfig.Servers)
                    {
                        //is the server new?
                        if (server.ServerID == -1)
                        {
                            server.Save();
                        }

                        //Lets grab the server object from the DB.
                        var dbServer = context.Servers.FirstOrDefault(x => x.ServerID == server.ServerID);
                        if (dbServer == null)
                        {
                            throw new Exception("Server not found in the config database");
                        }
                        shardSet.Servers.Add(dbServer);
                    }

                    if (shardSetConfig.ShardMap.ShardMapID == -1)
                    {
                        shardSetConfig.ShardMap = AddShardMap(shardSetConfig.ShardMap, context);
                    }

                    var dbShardSetConfig =
                        new Models.ShardSetConfig
                    {
                        AllowDeployment      = shardSetConfig.AllowDeployments,
                        MaxShardCount        = shardSetConfig.MaxShardCount,
                        MaxShardSizeMB       = shardSetConfig.MaxShardSizeMb,
                        MaxShardletsPerShard = shardSetConfig.MaxShardletsPerShard,
                        MinShardSizeMB       = shardSetConfig.MinShardSizeMb,
                        TargetShardCount     = shardSetConfig.TargetShardCount,
                        ShardMapID           = shardSetConfig.ShardMap.ShardMapID,
                        ShardSet             = shardSet,
                        Version = (shardSet.ShardSetConfigs.Count() + 1)
                    };

                    // create settings on the new configuration
                    foreach (var shardSetConfigSetting in shardSetConfig.ShardSetConfigSettings)
                    {
                        var setting = new ShardSetConfigSetting
                        {
                            SettingKey     = shardSetConfigSetting.SettingKey,
                            SettingValue   = shardSetConfigSetting.SettingValue,
                            ShardSetConfig = dbShardSetConfig
                        };

                        dbShardSetConfig.ShardSetConfigSettings.Add(setting);
                    }

                    context.ShardSetConfigs.Add(dbShardSetConfig);
                    context.SaveChanges();

                    shardSetConfig.ShardSetConfigID = dbShardSetConfig.ShardSetConfigID;
                    shardSetConfig.ShardSetID       = shardSet.ShardSetID;

                    AddPointerShards(context, shardSetConfig);

                    scope.Complete();
                }
            }

            return(shardSetConfig);
        }