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);
        }
Exemple #13
0
        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));
                }
            }
        }
Exemple #14
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));
        }
Exemple #15
0
        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.\"]}}}");
        }