Question : Adding Roles to Roles In Custom Membership Provider - A Better Way ? C#, SQL, Oracle, ASP.NET

I need to find a better way to save roles to roles in our custom mebership provider - as of rifgr now, here is the table :

ID(PK)
RoleID(FK To aspnet_Roles.ID)
ParentRoleID (FK to aspnet_Roles.ID)

Currently, here are the steps that are used to add a role (we will call this c-role) to another role (we will call this p-role)

- Get all of the current parent roles of the p-role, all of the parent's parent roles, all of the parent parent's parent roles, and so on and so on, and put the releventdata into a data table (as well as the same for the c-role .)

- Delete all of the entries for the c-role with a datatable of all of the c-roles parents

- Add the table we have collected that we just deleted, along with the new data concerning the parent role

I am hoping there is someone out there who has tackled this before, as I would like to find a better way to do this, as well as find a better way for the data access layer functionality that I have included below - everything works, I just want a quicker,  less complicated DAL, and if possible another option if available - thanks in advance for your knowledge!
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
// Starting call

        public bool SetRoles(DataTable dtRoles, string roleId)
        {
            DataTable dtDeleteRoles = GetParentRolesInRole(roleId);
            dtDeleteRoles.TableName = String.Format("RolesInRoles");
            CreatePrimaryKey(dtDeleteRoles, "Id");
            dtRoles.TableName = String.Format("RolesInRoles");
            bool result = UpdateTable(dtRoles, dtDeleteRoles);
            return result;
        }

// Here below are all the functions used in this call - anyone 
// slim this down at all, or find a better way ?

        public DataTable GetParentRolesInRole(string roleId)
        {
            string sqlCommand = (@"
                SELECT RolesInRoles.RoleId, aspnet_Roles.RoleName, RolesInRoles.ParentRoleId 
                FROM RolesInRoles 
                INNER JOIN aspnet_Roles
	                ON ParentRoleId = aspnet_Roles.RoleId
                WHERE RolesInRoles.RoleId = '{0}'
                ");
            sqlCommand = string.Format(sqlCommand, roleId);
            DbCommand dbCommand = _database.GetSqlStringCommand(sqlCommand);
            return _database.ExecuteDataSet(dbCommand).Tables[0];
        }


        public void CreatePrimaryKey(DataTable dtbTable, string strColumnName)
        {
            DataColumn[] dcCol = new DataColumn[1];
            dcCol[0] = dtbTable.Columns[strColumnName];
            dtbTable.PrimaryKey = dcCol;
        }


  public bool UpdateTable(DataTable add, DataTable delete)
        {
            using (DbConnection dbConn = _database.CreateConnection())
            {
                dbConn.Open();
                try
                {
                    using (DbTransaction dbTxn = dbConn.BeginTransaction())
                    {
                        try
                        {
                            if (add.Rows.Count > 0)
                            {
                                UpdateInsertDataTable(add, dbTxn);
                            }
                            if (delete.Rows.Count > 0)
                            {
                                for (int i = 0; i <= delete.Rows.Count - 1; i++)
                                {
                                    delete.Rows[i].Delete();
                                }
                                DeleteDataTable(delete, dbTxn);
                            }
                            dbTxn.Commit();
                        }
                        catch
                        {
                            dbTxn.Rollback();
                            return false;
                        }
                    }
                }
                finally
                {
                    dbConn.Close();
                }
            }
            return true;
        }

  private int UpdateInsertDataTable(DataTable dtTable, DbTransaction txn)
        {
            string strInsert = "INSERT INTO " + dtTable.TableName + " (";
            string strUpdate = "UPDATE " + dtTable.TableName + " SET ";

            for (int i = 0; i <= dtTable.Columns.Count - 1; i++)
            {
                if (_database.DbProviderFactory.ToString().Contains("Oracle"))
                {
                    strInsert = strInsert + dtTable.Columns[i].ColumnName + ",";
                    strUpdate = strUpdate + dtTable.Columns[i].ColumnName + " = " + _paramStart + dtTable.Columns[i].ColumnName + ",";
                }
                else
                {
                    strInsert = strInsert + "[" + dtTable.Columns[i].ColumnName + "],";
                    strUpdate = strUpdate + "[" + dtTable.Columns[i].ColumnName + "] = " + _paramStart + dtTable.Columns[i].ColumnName + ",";
                }
            }

            strInsert = strInsert.Substring(0, strInsert.Length - 1) + ") values (";
            for (int i = 0; i <= dtTable.Columns.Count - 1; i++)
            {
                strInsert = strInsert + _paramStart + dtTable.Columns[i].ColumnName + ",";
            }

            strInsert = strInsert.Substring(0, strInsert.Length - 1) + ")";
            strUpdate = strUpdate.Substring(0, strUpdate.Length - 1) + " WHERE ";
            foreach (DataColumn column in dtTable.PrimaryKey)
            {
                strUpdate = strUpdate + column.ColumnName + " = " + _paramStart + column.ColumnName + " AND ";
            }
            strUpdate = strUpdate.Substring(0, strUpdate.Length - 5);

            DbCommand insertCommand = _database.GetSqlStringCommand(strInsert);
            DbCommand updateCommand = _database.GetSqlStringCommand(strUpdate);

            for (int i = 0; i <= dtTable.Columns.Count - 1; i++)
            {
                DbType type = GetDataType(dtTable.Columns[i].DataType);
                _database.AddInParameter(insertCommand, dtTable.Columns[i].ColumnName, type, dtTable.Columns[i].ColumnName, DataRowVersion.Current);
                _database.AddInParameter(updateCommand, dtTable.Columns[i].ColumnName, type, dtTable.Columns[i].ColumnName, DataRowVersion.Current);
                if (!(type == DbType.String | type == DbType.AnsiString)) continue;
                insertCommand.Parameters[_paramStart + dtTable.Columns[i].ColumnName].Size = dtTable.Columns[i].MaxLength;
                updateCommand.Parameters[_paramStart + dtTable.Columns[i].ColumnName].Size = dtTable.Columns[i].MaxLength;
            }
            GetIdsForTable(dtTable);

            return UpdateDataSet(dtTable.Select("", ""), insertCommand, updateCommand, null, txn, UpdateBehavior.Standard, 0); //DataViewRowState.ModifiedCurrent | DataViewRowState.Added
        }

      private void GetIdsForTable(DataTable table)
        {
            if (table.Columns.Contains("Id"))
            {
                if (table.Columns["Id"].AutoIncrement == false)
                {
                    //For Each relation As DataRelation In table.ChildRelations 
                    // relation.Nested 
                    //Next 
                    int idEnd = GetLatestId(table.TableName); //GetIdRefs(table.TableName, rows.Length);
                    int id = idEnd + 1; //idEnd - rows.Length + 1;
                    foreach (DataRow row in table.Rows)
                    {
                        row["Id"] = id;
                        id += 1;
                    }
                }
            }

        }


 private int UpdateDataSet(DataRow[] dataRows, DbCommand insertCommand, DbCommand updateCommand, DbCommand deleteCommand, DbTransaction txn, UpdateBehavior behavior, int updateBatchSize)
        {
            int rows;
            using (DbDataAdapter adapter = _database.GetDataAdapter())
            {
                if ((behavior == UpdateBehavior.Transactional) & txn == null)
                {
                    using (DbConnection dbConn = _database.CreateConnection())
                    {
                        dbConn.Open();
                        try
                        {
                            using (DbTransaction dbTxn = dbConn.BeginTransaction())
                            {
                                try
                                {
                                    DoUpdateDataSet(adapter, insertCommand, updateCommand, deleteCommand, dbTxn, behavior, updateBatchSize);
                                    rows = adapter.Update(dataRows);
                                    dbTxn.Commit();
                                }
                                catch
                                {
                                    dbTxn.Rollback();
                                    throw;
                                }
                            }
                        }
                        finally
                        {
                            dbConn.Close();
                        }
                    }
                }
                else
                {
                    DoUpdateDataSet(adapter, insertCommand, updateCommand, deleteCommand, txn, behavior, updateBatchSize);
                    rows = adapter.Update(dataRows);
                }
            }
            return rows;
        }

 private static void DoUpdateDataSet(DbDataAdapter adapter, DbCommand insertCommand, DbCommand updateCommand, DbCommand deleteCommand, DbTransaction txn, UpdateBehavior behavior, int updateBatchSize)
        {

            IDbDataAdapter explicitAdapter = adapter;
            if (txn != null)
            {
                if (insertCommand != null)
                    PrepareCommand(insertCommand, txn);
                if (updateCommand != null)
                    PrepareCommand(updateCommand, txn);
                if (deleteCommand != null)
                    PrepareCommand(deleteCommand, txn);
            }
            if (insertCommand != null)
            {
                insertCommand.CommandTimeout = 120;
                explicitAdapter.InsertCommand = insertCommand;
            }
            if (updateCommand != null)
            {
                updateCommand.CommandTimeout = 120;
                explicitAdapter.UpdateCommand = updateCommand;
            }
            if (deleteCommand != null)
            {
                deleteCommand.CommandTimeout = 120;
                explicitAdapter.DeleteCommand = deleteCommand;
            }

            if (updateBatchSize == 1) return;
            adapter.UpdateBatchSize = updateBatchSize;
            if (insertCommand != null)
                adapter.InsertCommand.UpdatedRowSource = UpdateRowSource.None;
            if (updateCommand != null)
                adapter.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;
            if (deleteCommand != null)
                adapter.DeleteCommand.UpdatedRowSource = UpdateRowSource.None;
        }

        private static void PrepareCommand(DbCommand command, DbTransaction txn)
        {
            command.Transaction = txn;
            command.Connection = txn.Connection;
            command.Prepare();
        }

   private int DeleteDataTable(DataTable dtTable, DbTransaction txn)
        {
            string strDelete = "delete from " + dtTable.TableName + " where ";
            foreach (DataColumn column in dtTable.PrimaryKey)
            {
                strDelete = strDelete + column.ColumnName + " = " + _paramStart + column.ColumnName + " and ";
            }
            strDelete = strDelete.Substring(0, strDelete.Length - 5);
            DbCommand deleteCommand = _database.GetSqlStringCommand(strDelete);
            //For Each row As Data.DataRow In dtTable.Rows 
            foreach (DataColumn column in dtTable.PrimaryKey)
            {
                //db.AddInParameter(deleteCommand, column.ColumnName, GetDataType(column.DataType), row.Item(column.ColumnName, DataRowVersion.Original)) 
                _database.AddInParameter(deleteCommand, column.ColumnName, GetDataType(column.DataType), column.ColumnName, DataRowVersion.Current);
            }
            return UpdateDataSet(dtTable.Select("", "", DataViewRowState.Deleted), null, null, deleteCommand, txn, UpdateBehavior.Standard, 0);
        }

Answer : Adding Roles to Roles In Custom Membership Provider - A Better Way ? C#, SQL, Oracle, ASP.NET

Bits are bits, you can only make the transfer quicker by having both a bigger pipe to/from the storage, and a faster storage array.  

Snapshots are on the fly, you can even schedule them.  Then you can perform a backup on the snapshot with the VM still running.  Again, BEWARE of performance degradation on your storage array.

You can absolutely automate the shutdown, export and recovery.  You can count on the VMs to come back up as long as your scripting is good and well tested.

Pretty much everything you want is already in the 5.6 release of XenServer.  Also check out StorageLink, which comes with XS Enterprise, and further enhances these functions.
Random Solutions  
 
programming4us programming4us