private ISuccessOrErrors CheckColumn(SqlColumnInfo sqlCol, EfColumnInfo clrCol, string combinedName) { var status = new SuccessOrErrors(); if (sqlCol.SqlTypeName != clrCol.SqlTypeName) { status.AddSingleError( "Column Type: The SQL {0} column {1}.{2} type does not match EF. SQL type = {3}, EF type = {4}.", _sqlDbRefString, combinedName, clrCol.SqlColumnName, sqlCol.SqlTypeName, clrCol.SqlTypeName); } if (sqlCol.IsNullable != clrCol.IsNullable) { status.AddSingleError( "Column Nullable: SQL {0} column {1}.{2} nullablity does not match. SQL is {3}NULL, EF is {4}NULL.", _sqlDbRefString, combinedName, clrCol.SqlColumnName, sqlCol.IsNullable ? "" : "NOT ", clrCol.IsNullable ? "" : "NOT "); } if (sqlCol.IsPrimaryKey != clrCol.IsPrimaryKey) { status.AddSingleError( "Primary Key: The SQL {0} column {1}.{2} primary key settings don't match. SQL says it is {3}a key, EF says it is {4}a key.", _sqlDbRefString, combinedName, clrCol.SqlColumnName, sqlCol.IsPrimaryKey ? "" : "NOT ", clrCol.IsPrimaryKey ? "" : "NOT "); } else if (sqlCol.IsPrimaryKey && sqlCol.PrimaryKeyOrder != clrCol.PrimaryKeyOrder) { status.AddSingleError( "Primary Key Order: The SQL {0} column {1}.{2} primary key order does not match. SQL order = {3}, EF order = {4}.", _sqlDbRefString, combinedName, clrCol.SqlColumnName, sqlCol.PrimaryKeyOrder, clrCol.PrimaryKeyOrder); } return(status.Combine(CheckMaxLength(sqlCol, clrCol, combinedName))); }
public ISuccessOrErrors <TDto> Get <TDto>(params object[] identifiers) where TDto : DtoBase <TContext, TEntity, TDto>, new() { var status = new SuccessOrErrors <TDto>(); if (!new TDto().AllowedActions.HasFlag(ActionFlags.Get)) { return(status.AddSingleError("Dto is not allowed for this kind of action")); } var entity = dbContext.Set <TEntity>() .Where(BuildFilter.CreateFilter <TEntity>(dbContext.GetKeyProperties <TEntity>(), identifiers)) .SingleOrDefault(); var dto = DTORepositoryContainer.Mapper.Map <TDto>(entity, opts => { opts.Items["ActionFlags"] = ActionFlags.Get; opts.Items["DbContext"] = dbContext; }); if (dto != null) { return(status.SetSuccessWithResult(dto, "Success")); } return(status.AddSingleError("Not found")); }
public void Test11CheckConvertResultToNormalStatusNotValidOk() { //SETUP var statusWithResult = new SuccessOrErrors <string>(); statusWithResult.AddSingleError("There was an error"); //ATTEMPT var status = statusWithResult as ISuccessOrErrors; //VERIFY status.IsValid.ShouldEqual(false); status.HasErrors.ShouldEqual(true); }
public void Test16CheckConvertResultToNormalStatusNotValidOk() { //SETUP var statusWithResult = new SuccessOrErrors(); statusWithResult.AddSingleError("error"); //ATTEMPT var status = SuccessOrErrors <string> .ConvertNonResultStatus(statusWithResult); //VERIFY status.IsValid.ShouldEqual(false); status.HasErrors.ShouldEqual(true); }
/// <summary> /// This will take an IQueryable request and add single on the end to realise the request. /// It catches if the single didn't produce an item /// </summary> /// <typeparam name="T"></typeparam> /// <param name="request">An IQueryable request with a filter that yeilds a single item</param> /// <param name="methodName">Do not specify. System fills this in with the calling method</param> /// <returns>Returns task with status. If Valid then status.Result is the single item, otherwise an new, empty class</returns> public static async Task <ISuccessOrErrors <T> > RealiseSingleWithErrorCheckingAsync <T>(this IQueryable <T> request, [CallerMemberName] string methodName = "") where T : class, new() { var status = new SuccessOrErrors <T>(new T(), "we return empty class if it fails"); try { var result = await request.SingleOrDefaultAsync(); if (result == null) { status.AddSingleError( "We could not find an entry using that filter. Has it been deleted by someone else?"); } else { status.SetSuccessWithResult(result, "successful"); } } catch (Exception ex) { if (GenericServicesConfig.RealiseSingleExceptionMethod == null) { throw; //nothing to catch error } var errMsg = GenericServicesConfig.RealiseSingleExceptionMethod(ex, methodName); if (errMsg != null) { status.AddSingleError(errMsg); } else { throw; //do not understand the error so rethrow } } return(status); }
public void Check10AddSingleErrorOk() { //SETUP var status = new SuccessOrErrors(); //ATTEMPT status.AddSingleError("This was {0}.", "bad"); //VERIFY status.IsValid.ShouldEqual(false); status.SuccessMessage.ShouldEqual(""); status.Errors.Count.ShouldEqual(1); status.Errors[0].ErrorMessage.ShouldEqual("This was bad."); status.Errors[0].MemberNames.Count().ShouldEqual(0); }
public void Check20StatusToJsonTopLevel() { //SETUP var status = new SuccessOrErrors(); var dto = new { MyInt = 1 }; //ATTEMPT status.AddSingleError("This is a top level error."); var jsonResult = status.ReturnErrorsAsJson(dto); //VERIFY var json = jsonResult.Data.SerialiseToJson(); json.ShouldEqual("{\"errorsDict\":{\"\":{\"errors\":[\"This is a top level error.\"]}}}"); }
public void Test04AddSingleErrorOk() { //SETUP var status = new SuccessOrErrors<string>(); //ATTEMPT status.AddSingleError("This was {0}.", "bad"); //VERIFY status.IsValid.ShouldEqual(false); status.HasErrors.ShouldEqual(true); status.SuccessMessage.ShouldEqual(""); status.Result.ShouldEqual(null); status.Errors.Count.ShouldEqual(1); status.Errors[0].ErrorMessage.ShouldEqual("This was bad."); status.Errors[0].MemberNames.Count().ShouldEqual(0); }
public void Test04AddSingleErrorOk() { //SETUP var status = new SuccessOrErrors <string>(); //ATTEMPT status.AddSingleError("This was {0}.", "bad"); //VERIFY status.IsValid.ShouldEqual(false); status.HasErrors.ShouldEqual(true); status.SuccessMessage.ShouldEqual(""); status.Result.ShouldEqual(null); status.Errors.Count.ShouldEqual(1); status.Errors[0].ErrorMessage.ShouldEqual("This was bad."); status.Errors[0].MemberNames.Count().ShouldEqual(0); }
public ISuccessOrErrors <IList <TDto> > Query <TDto>(Expression <Func <TEntity, bool> > predicate = null) where TDto : DtoBase <TContext, TEntity, TDto>, new() { var status = new SuccessOrErrors <IList <TDto> >(); //var dtos = dbContext.Set<TEntity>().Where(predicate).ProjectTo<TDto>(DtoHelper.Mapper.ConfigurationProvider).ToList(); if (!new TDto().AllowedActions.HasFlag(ActionFlags.List)) { return(status.AddSingleError("Dto is not allowed for this kind of action")); } var dtos = new DTOQueryable <TContext, TEntity, TDto>(dbContext, opts => { opts.Items["ActionFlags"] = ActionFlags.List; opts.Items["DbContext"] = dbContext; }, dbContext.Set <TEntity>().Where(predicate)).ToList(); return(status.SetSuccessWithResult(dtos, "Success")); }
public void Test31CombineAddOtherSingleErrorOk() { //SETUP var status1 = new SuccessOrErrors <string>(); var status2 = new SuccessOrErrors(); status2.AddSingleError("This was {0}.", "bad"); //ATTEMPT status1.Combine(status2); //VERIFY status1.IsValid.ShouldEqual(false); status1.HasErrors.ShouldEqual(true); status1.SuccessMessage.ShouldEqual(""); status1.Errors.Count.ShouldEqual(1); status1.Errors[0].ErrorMessage.ShouldEqual("This was bad."); status1.Errors[0].MemberNames.Count().ShouldEqual(0); }
public ActionResult AjaxFormReturn(TestAjaxFormModel model) { if (!ModelState.IsValid) { //model errors so return errors return ModelState.ReturnModelErrorsAsJson(); } if (!model.ShouldFail) { return Json(new { SuccessMessage = "This was successful" }); } //else errors, so send back the errors var status = new SuccessOrErrors(); status.AddSingleError("The ShouldFail flag was set, which causes a service failure."); status.AddNamedParameterError("ShouldFail", "This should be false for this to work."); return status.ReturnErrorsAsJson(model); }
public ISuccessOrErrors <int> ExecuteNonQuery(string command) { var status = new SuccessOrErrors <int>(); using (var myConn = new SqlConnection(_connectionString)) { var myCommand = new SqlCommand(command, myConn); try { myConn.Open(); var numRows = myCommand.ExecuteNonQuery(); return(status.SetSuccessWithResult(numRows, "Successfully ran sql non-query.")); } catch (System.Exception ex) { return(status.AddSingleError("{0}: in sql non-query command. Message = {1}", ex.GetType().Name, ex.Message)); } } }
public ActionResult AjaxFormReturn(TestAjaxFormModel model) { if (!ModelState.IsValid) { //model errors so return errors return(ModelState.ReturnModelErrorsAsJson()); } if (!model.ShouldFail) { return(Json(new { SuccessMessage = "This was successful" })); } //else errors, so send back the errors var status = new SuccessOrErrors(); status.AddSingleError("The ShouldFail flag was set, which causes a service failure."); status.AddNamedParameterError("ShouldFail", "This should be false for this to work."); return(status.ReturnErrorsAsJson(model)); }
public ISuccessOrErrors <int> ExecuteRowCount(string tableName, string whereClause = "") { var status = new SuccessOrErrors <int>(); using (var myConn = new SqlConnection(_connectionString)) { var command = "SELECT COUNT(*) FROM " + tableName + " " + whereClause; var myCommand = new SqlCommand(command, myConn); try { myConn.Open(); return(status.SetSuccessWithResult((int)myCommand.ExecuteScalar(), "Successfully ran sql row query count.")); } catch (System.Exception ex) { return(status.AddSingleError("{0}: in sql query command. Message = {1}", ex.GetType().Name, ex.Message)); } } }
public ISuccessOrErrors ApplyMigrations(string dbConnectionString) { var status = new SuccessOrErrors(); var upgrader = DeployChanges.To .SqlDatabase(dbConnectionString) .WithScriptsAndCodeEmbeddedInAssembly(Assembly.GetExecutingAssembly()) .WithTransaction() .LogToConsole() .Build(); var result = upgrader.PerformUpgrade(); if (result.Successful) { var msg = result.Scripts.Any() ? "Successfully applied the last " + result.Scripts.Count() + " script(s) to the database." : "No updates done to database."; return(status.SetSuccessMessage(msg)); } return(status.HasErrors ? status : status.AddSingleError(result.Error.Message)); }
public void Test50SingleErrorGetAllErrorsOk() { //SETUP var status = new SuccessOrErrors(); //ATTEMPT status.AddSingleError("This was {0}.", "bad"); var str = status.GetAllErrors(); //VERIFY str.ShouldEqual("This was bad."); }
/// <summary> /// This checks that the EF relationship is mirrored in the SQL /// </summary> /// <param name="tableInfo"></param> /// <param name="relEfCol"></param> /// <returns>returns status with optional name of SQL many-many table. Used to mark that table as having been used</returns> public ISuccessOrErrors <string> CheckEfRelationshipToSql(EfTableInfo tableInfo, EfRelationshipInfo relEfCol) { var status = new SuccessOrErrors <string>(); string manyToManyTableName = null; if (relEfCol.FromToRelationships.FromMultiplicity == EfRelationshipTypes.Many) { //handle from many if (relEfCol.FromToRelationships.ToMultiplicity == EfRelationshipTypes.Many) { //many to many - look for a linking table in the list of _potentialManyToManyTablesDict that has the right foreignKeys var fromEfTable = GetEfTableDataFromClass(tableInfo.ClrClassType); var toEfTable = GetEfTableDataFromCollection(relEfCol); var fromKeys = fromEfTable.NormalCols.Where(x => x.IsPrimaryKey); var toKeys = toEfTable.NormalCols.Where(x => x.IsPrimaryKey); var linkCombinedNames = AllManyToManyTablesThatHaveTheRightForeignKeys(fromKeys, toKeys, fromEfTable.TableName, toEfTable.TableName).ToList(); if (!linkCombinedNames.Any()) { status.AddSingleError( "Missing Link Table: EF has a {0} relationship between {1}.{2} and {3} but we could not find a linking table with the right foreign keys.", relEfCol.FromToRelationships, tableInfo.TableName, relEfCol.ClrColumnName, toEfTable.TableName); } else { //now we check the entries in the linking tab if (linkCombinedNames.Count > 1) { status.AddWarning( "Ambigous Link Table: EF has a {0} relationship between {1}.{2} and {3}. This was ambigous so we may not have fully checked this.", relEfCol.FromToRelationships, tableInfo.TableName, relEfCol.ClrColumnName, toEfTable.TableName); } manyToManyTableName = linkCombinedNames.First(); foreach (var foreignKey in _allSqlInfo.ForeignKeys.Where(x => x.ParentTableNameWithScheme == manyToManyTableName) .Where(foreignKey => !foreignKey.IsCascade)) { status.AddSingleError( "Cascade Delete: The {0} relationship between {1}.{2} and {3} has a foreign key {4} that is not CASCASE DELETE." + " All linking table foreign keys should have CASCASE DELETE.", relEfCol.FromToRelationships, tableInfo.TableName, relEfCol.ClrColumnName, toEfTable.TableName, foreignKey.ConstraintName); } } } else { //many to one var toSqlTableStatus = GetSqlTableDataFromClass(relEfCol.ClrColumnType); if (toSqlTableStatus.HasErrors) { return(status.Combine(toSqlTableStatus)); } var foreignKeys = GetForeignKeys(tableInfo.TableName, toSqlTableStatus.Result); if (!foreignKeys.Any()) { status.AddSingleError( "Missing Foreign Key: EF has a {0} relationship between {1}.{2} and {3} but we don't find that in SQL.", relEfCol.FromToRelationships, tableInfo.TableName, relEfCol.ClrColumnName, toSqlTableStatus.Result.TableName); } else { //Look at cascase deletes foreach (var foreignKey in foreignKeys.Where(foreignKey => relEfCol.FromToRelationships.ToIsCascadeDelete != foreignKey.IsCascade)) { status.AddSingleError( "Cascade Delete: The {0} relationship between {1}.{2} and {3} has different cascase delete value." + " SQL foreign key say {4}, EF setting is {5}.", relEfCol.FromToRelationships, tableInfo.TableName, relEfCol.ClrColumnName, toSqlTableStatus.Result.TableName, foreignKey.DeleteAction, relEfCol.FromToRelationships.ToIsCascadeDelete ? "CASCADE" : "NO_ACTION"); } } } } else { //The parent is single, which implies that the child holds the key if (relEfCol.FromToRelationships.ToMultiplicity == EfRelationshipTypes.Many) { //typical one to many var fromSqlTableStatus = GetSqlTableDataFromCollection(relEfCol); if (fromSqlTableStatus.HasErrors) { return(status.Combine(fromSqlTableStatus)); } var toSqlTable = _sqlInfoDict[tableInfo.CombinedName]; var foreignKeys = GetForeignKeys(fromSqlTableStatus.Result.TableName, toSqlTable); if (!foreignKeys.Any()) { status.AddSingleError( "Missing Foreign Key: EF has a {0} relationship between {1} and {2}.{3} but we don't find that in SQL.", relEfCol.FromToRelationships, fromSqlTableStatus.Result.TableName, tableInfo.TableName, relEfCol.ClrColumnName); } else { //Look at cascase deletes foreach (var foreignKey in foreignKeys.Where(foreignKey => relEfCol.FromToRelationships.FromIsCascadeDelete != foreignKey.IsCascade)) { status.AddSingleError( "Cascade Delete: The {0} relationship between {1}.{2} and {3} has different cascase delete value." + " SQL foreign key say {4}, EF setting is {5}.", relEfCol.FromToRelationships, tableInfo.TableName, relEfCol.ClrColumnName, toSqlTable.TableName, foreignKey.DeleteAction, relEfCol.FromToRelationships.ToIsCascadeDelete ? "CASCADE" : "NO_ACTION"); } } } else { //one to one/OneOrZero or reverse var sqlTableEnd1Status = GetSqlTableDataFromClass(relEfCol.ClrColumnType); if (sqlTableEnd1Status.HasErrors) { return(status.Combine(sqlTableEnd1Status)); } var sqlTableEnd2 = _sqlInfoDict[tableInfo.CombinedName]; //There is one foreign key for both directions. Therefore we need to check both var foreignKey1 = GetForeignKeys(sqlTableEnd1Status.Result.TableName, sqlTableEnd2).SingleOrDefault(); var foreignKey2 = GetForeignKeys(sqlTableEnd2.TableName, sqlTableEnd1Status.Result).SingleOrDefault(); if (foreignKey1 == null && foreignKey2 == null) { status.AddSingleError( "Missing Foreign Key: EF has a {0} relationship between {1}.{2} and {3} but we don't find that in SQL.", relEfCol.FromToRelationships, tableInfo.TableName, relEfCol.ClrColumnName, sqlTableEnd1Status.Result.TableName); } else if (foreignKey1 != null && relEfCol.FromToRelationships.FromIsCascadeDelete != foreignKey1.IsCascade) { //Look at cascase deletes status.AddSingleError( "Cascade Delete: The {0} relationship between {1}.{2} and {3} has different cascase delete value." + " SQL foreign key say {4}, EF setting is {5}.", relEfCol.FromToRelationships, tableInfo.TableName, relEfCol.ClrColumnName, sqlTableEnd1Status.Result.TableName, foreignKey1.DeleteAction, relEfCol.FromToRelationships.ToIsCascadeDelete ? "CASCADE" : "NO_ACTION"); } else if (foreignKey2 != null && relEfCol.FromToRelationships.ToIsCascadeDelete != foreignKey2.IsCascade) { //Look at cascase deletes status.AddSingleError( "Cascade Delete: The {0} relationship between {1}.{2} and {3} has different cascase delete value." + " SQL foreign key say {4}, EF setting is {5}.", relEfCol.FromToRelationships, tableInfo.TableName, relEfCol.ClrColumnName, sqlTableEnd1Status.Result.TableName, foreignKey1.DeleteAction, relEfCol.FromToRelationships.ToIsCascadeDelete ? "CASCADE" : "NO_ACTION"); } } } return(status.HasErrors ? status : status.SetSuccessWithResult(manyToManyTableName, "All Ok")); }
public void Test54MultipleErrorsGetAllErrorsOk() { //SETUP var status = new SuccessOrErrors(); //ATTEMPT status.AddSingleError("This was {0}.", "bad"); status.AddNamedParameterError("MyParameterName", "This was {0}.", "bad"); var str = status.GetAllErrors(); //VERIFY str.ShouldEqual("This was bad.\nMyParameterName: This was bad."); }
public void Test51SingleErrorAsHtmlOk() { //SETUP var status = new SuccessOrErrors(); //ATTEMPT status.AddSingleError("This was {0}.", "bad"); var html = status.ErrorsAsHtml(); //VERIFY html.ShouldEqual("<p>This was bad.</p>"); }
public void Test55MultipleErrorsAsHtmlOk() { //SETUP var status = new SuccessOrErrors(); //ATTEMPT status.AddSingleError("This was {0}.", "bad"); status.AddNamedParameterError("MyParameterName", "This was {0}.", "bad"); var html = status.ErrorsAsHtml(); //VERIFY html.ShouldEqual("<ul><li>This was bad.</li><li>MyParameterName: This was bad.</li></ul>"); }
public void Test11CheckConvertResultToNormalStatusNotValidOk() { //SETUP var statusWithResult = new SuccessOrErrors<string>(); statusWithResult.AddSingleError("There was an error"); //ATTEMPT var status = statusWithResult as ISuccessOrErrors; //VERIFY status.IsValid.ShouldEqual(false); status.HasErrors.ShouldEqual(true); }
public void Test16CheckConvertResultToNormalStatusNotValidOk() { //SETUP var statusWithResult = new SuccessOrErrors(); statusWithResult.AddSingleError("error"); //ATTEMPT var status = SuccessOrErrors<string>.ConvertNonResultStatus(statusWithResult); //VERIFY status.IsValid.ShouldEqual(false); status.HasErrors.ShouldEqual(true); }
public void Test31CombineAddOtherSingleErrorOk() { //SETUP var status1 = new SuccessOrErrors<string>(); var status2 = new SuccessOrErrors(); status2.AddSingleError("This was {0}.", "bad"); //ATTEMPT status1.Combine(status2); //VERIFY status1.IsValid.ShouldEqual(false); status1.HasErrors.ShouldEqual(true); status1.SuccessMessage.ShouldEqual(""); status1.Errors.Count.ShouldEqual(1); status1.Errors[0].ErrorMessage.ShouldEqual("This was bad."); status1.Errors[0].MemberNames.Count().ShouldEqual(0); }
public void Check20StatusToJsonTopLevel() { //SETUP var status = new SuccessOrErrors(); var dto = new {MyInt = 1}; //ATTEMPT status.AddSingleError("This is a top level error."); var jsonResult = status.ReturnErrorsAsJson(dto); //VERIFY var json = jsonResult.Data.SerialiseToJson(); json.ShouldEqual("{\"errorsDict\":{\"\":{\"errors\":[\"This is a top level error.\"]}}}"); }