public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
        {
            Debug.Assert(context != null);
            SecUtility.CheckParameter(ref id, true, true, false, TableStorageConstants.MaxStringPropertySizeInChars, "id");
            if (timeout < 0)
            {
                throw new ArgumentException("Parameter timeout must be a non-negative integer!");
            }

            try
            {
                TableStorageDataServiceContext svc = CreateDataServiceContext();
                SessionRow session = new SessionRow(id, _applicationName);

                session.Lock        = 0; // no lock
                session.Initialized = false;
                session.Id          = id;
                session.Timeout     = timeout;
                session.ExpiresUtc  = DateTime.UtcNow.AddMinutes(timeout);
                svc.AddObject(_tableName, session);
                svc.SaveChangesWithRetries();
            } catch (InvalidOperationException e) {
                throw new ProviderException("Error accessing the data store.", e);
            }
        }
        // Because of limited transactional support in the table storage offering, this function gives limited guarantees
        // for inserting all users into all roles.
        // We do not recommend using this function because of missing transactional support.
        public override void AddUsersToRoles(string[] usernames, string[] roleNames)
        {
            SecUtility.CheckArrayParameter(ref roleNames, true, true, true, MaxTableRoleNameLength, "roleNames");
            SecUtility.CheckArrayParameter(ref usernames, true, true, true, Constants.MaxTableUsernameLength, "usernames");

            RoleRow row;

            try
            {
                TableStorageDataServiceContext svc = CreateDataServiceContext();
                foreach (string role in roleNames)
                {
                    if (!RoleExists(role))
                    {
                        throw new ProviderException(string.Format(CultureInfo.InstalledUICulture, "The role {0} does not exist!", role));
                    }
                    foreach (string user in usernames)
                    {
                        row = new RoleRow(_applicationName, role, user);
                        try
                        {
                            svc.AddObject(_tableName, row);
                            svc.SaveChangesWithRetries();
                        }
                        catch (InvalidOperationException e)
                        {
                            HttpStatusCode status;
                            if (TableStorageHelpers.EvaluateException(e, out status) && status == HttpStatusCode.Conflict)
                            {
                                // this element already exists or was created in a failed retry
                                // this is not a fatal error; continue adding elements
                                Log.Write(EventKind.Warning, string.Format(CultureInfo.InstalledUICulture, "The user {0} already exists in the role {1}.", user, role));
                                svc.Detach(row);
                            }
                            else
                            {
                                throw new ProviderException(string.Format(CultureInfo.InstalledUICulture, "Error adding user {0} to role {1}", user, role));
                            }
                        }
                    }
                }
            }
            catch (InvalidOperationException e)
            {
                throw new ProviderException("Error while accessing the data store.", e);
            }
        }
        public override void CreateRole(string roleName)
        {
            SecUtility.CheckParameter(ref roleName, true, true, true, MaxTableRoleNameLength, "rolename");

            try
            {
                TableStorageDataServiceContext svc = CreateDataServiceContext();
                RoleRow newRole = new RoleRow(_applicationName, roleName, string.Empty);
                svc.AddObject(_tableName, newRole);
                svc.SaveChangesWithRetries();
            }
            catch (InvalidOperationException e)
            {
                HttpStatusCode status;
                // when retry policies are used we cannot distinguish between a conflict and success
                // so, in the case of a conflict, we just retrun success here
                if (TableStorageHelpers.EvaluateException(e, out status) && status == HttpStatusCode.Conflict)
                {
                    return;
                    // the role already exists
                }
                throw new ProviderException("Error accessing role table.", e);
            }
        }
        public override void SetAndReleaseItemExclusive(HttpContext context, string id,
                                                        SessionStateStoreData item, object lockId, bool newItem)
        {
            Debug.Assert(context != null);
            SecUtility.CheckParameter(ref id, true, true, false, TableStorageConstants.MaxStringPropertySizeInChars, "id");

            _providerRetry(() =>
            {
                TableStorageDataServiceContext svc = CreateDataServiceContext();
                SessionRow session;

                if (!newItem)
                {
                    session = GetSession(id, svc);
                    if (session == null || session.Lock != (int)lockId)
                    {
                        Debug.Assert(false);
                        return;
                    }
                }
                else
                {
                    session             = new SessionRow(id, _applicationName);
                    session.Lock        = 1;
                    session.LockDateUtc = DateTime.UtcNow;
                }
                session.Initialized = true;
                Debug.Assert(session.Timeout >= 0);
                session.Timeout    = item.Timeout;
                session.ExpiresUtc = DateTime.UtcNow.AddMinutes(session.Timeout);
                session.Locked     = false;

                // yes, we always create a new blob here
                session.BlobName = GetBlobNamePrefix(id) + Guid.NewGuid().ToString("N");


                // Serialize the session and write the blob
                byte[] items, statics;
                SerializeSession(item, out items, out statics);
                string serializedItems   = Convert.ToBase64String(items);
                string serializedStatics = Convert.ToBase64String(statics);
                MemoryStream output      = new MemoryStream();
                StreamWriter writer      = new StreamWriter(output);

                try
                {
                    writer.WriteLine(serializedItems);
                    writer.WriteLine(serializedStatics);
                    writer.Flush();
                    // for us, it shouldn't matter whether newItem is set to true or false
                    // because we always create the entire blob and cannot append to an
                    // existing one
                    _blobProvider.UploadStream(session.BlobName, output);
                    writer.Close();
                    output.Close();
                }
                catch (Exception e)
                {
                    if (!newItem)
                    {
                        ReleaseItemExclusive(svc, session, lockId);
                    }
                    throw new ProviderException("Error accessing the data store.", e);
                }
                finally
                {
                    if (writer != null)
                    {
                        writer.Close();
                    }
                    if (output != null)
                    {
                        output.Close();
                    }
                }

                if (newItem)
                {
                    svc.AddObject(_tableName, session);
                    svc.SaveChangesWithRetries();
                }
                else
                {
                    // Unlock the session and save changes
                    ReleaseItemExclusive(svc, session, lockId);
                }
            });
        }
        // shows alternative ways of generating DataServiceContext objects
        internal static void RunSamples2()
        {
            StorageAccountInfo account = null;

            try
            {
                account = StorageAccountInfo.GetDefaultTableStorageAccountFromConfiguration();
                TableStorage tableStorage = TableStorage.Create(account);
                tableStorage.RetryPolicy = RetryPolicies.RetryN(3, TimeSpan.FromSeconds(1));
                // the DataServiceContext object inherits its retry policy from tableStorage in this case
                TableStorageDataServiceContext svc = tableStorage.GetDataServiceContext();


                Console.WriteLine("Table creation, delete and list samples...");
                string sampleTableName = SampleDataServiceContext.SampleTableName;
                tableStorage.TryCreateTable(sampleTableName);

                DeleteAllEntriesFromSampleTable(svc, sampleTableName);

                Console.WriteLine("List all tables in the account.");
                IEnumerable <string> tables2 = tableStorage.ListTables();
                foreach (string n1 in tables2)
                {
                    Console.WriteLine(n1);
                }

                Console.WriteLine("Inserting entities into the table...");

                SampleEntity t = new SampleEntity("samplepartitionkey", "samplerowkey");
                svc.AddObject(sampleTableName, t);
                svc.SaveChangesWithRetries();

                //Detach the existing entity so that we can demonstrate the server side
                //error when you try to insert an same object with the same keys
                svc.Detach(t);

                // Insert an entity with the same keys
                Console.WriteLine("Try to insert the same entity into the table and show how to deal with error conditions.");

                t = new SampleEntity("samplepartitionkey", "samplerowkey");
                svc.AddObject(sampleTableName, t);
                try
                {
                    svc.SaveChangesWithRetries();
                    // getting here is an error because inserting the same row twice raises an exception
                    Console.WriteLine("Should not get here. Succeeded inserting two entities with the same keys");
                }
                catch (Exception e)
                {
                    HttpStatusCode status;
                    StorageExtendedErrorInformation errorInfo;
                    if (TableStorageHelpers.EvaluateException(e, out status, out errorInfo) &&
                        status == HttpStatusCode.Conflict)
                    {
                        // the row has already been inserted before, this is expected here
                        if (errorInfo != null)
                        {
                            Console.WriteLine("Attempting to insert row with same keys resulted in error {0} : {1}",
                                              errorInfo.ErrorCode, errorInfo.ErrorMessage);
                        }
                    }
                    else
                    {
                        throw;
                    }
                }

                svc.Detach(t);

                Console.WriteLine("Insert a large item into the table.");
                t   = new SampleEntity("samplepartitionkey", "samplerowkey1");
                t.B = new String('a', 1000);
                svc.AddObject(sampleTableName, t);
                svc.SaveChangesWithRetries();

                Console.WriteLine("Create a normal DataServiceContext object (not TableStorageDataServiceContext) and attach it to a TableStorage object.");
                DataServiceContext svc2 = new DataServiceContext(
                    TableStorage.GetServiceBaseUri(account.BaseUri, account.UsePathStyleUris, account.AccountName));
                tableStorage.Attach(svc2);

                var qResult = from c in svc2.CreateQuery <SampleEntity>(sampleTableName)
                              where c.RowKey == "samplerowkey1"
                              select c;

                foreach (SampleEntity cust in qResult)
                {
                    if (cust.B != t.B)
                    {
                        Console.WriteLine("Sample failed. Did not read the entity property just written");
                    }
                }

                Console.WriteLine("Insert many rows in a table and show the API for dealing with query result pagination.");

                int num = 2100;
                Console.WriteLine("Inserting {0} rows.", num.ToString(CultureInfo.CurrentUICulture));
                for (int i = 0; i < num; i++)
                {
                    t = new SampleEntity("samplestring", i.ToString(CultureInfo.InvariantCulture));
                    svc.AddObject(sampleTableName, t);
                    svc.SaveChangesWithRetries();
                    if ((i + 1) % 50 == 0)
                    {
                        Console.WriteLine("Inserted row {0}.", (i + 1).ToString(CultureInfo.CurrentUICulture));
                    }
                }

                Console.WriteLine("Executing query that will return many results. This can take a while...");
                var qResult2 = from c in svc.CreateQuery <SampleEntity>(sampleTableName)
                               where c.PartitionKey == "samplestring"
                               select c;

                TableStorageDataServiceQuery <SampleEntity> tableStorageQuery = new TableStorageDataServiceQuery <SampleEntity>(qResult2 as DataServiceQuery <SampleEntity>);
                IEnumerable <SampleEntity> res = tableStorageQuery.ExecuteAllWithRetries();
                Console.WriteLine("Retrieved query results:");
                foreach (SampleEntity entity in res)
                {
                    Console.WriteLine("Partition key: {0}, row key: {1}.", entity.PartitionKey, entity.RowKey);
                }

                Console.WriteLine("Delete all entries in the sample table.");
                DeleteAllEntriesFromSampleTable(tableStorage.GetDataServiceContext(), sampleTableName);
                tableStorage.DeleteTable(sampleTableName);
                Console.WriteLine("Table samples finished!");
            }
            catch (DataServiceRequestException dsre)
            {
                Console.WriteLine("DataServiceRequestException: " + GetExceptionMessage(dsre));
                ShowTableStorageErrorMessage(account.BaseUri.ToString());
            }
            catch (InvalidOperationException ioe)
            {
                Console.WriteLine("Storage service error: " + GetExceptionMessage(ioe));
                ShowTableStorageErrorMessage(account.BaseUri.ToString());
            }
        }