public virtual string ToAddForeignKeyStatement <T, TForeign>(Expression <Func <T, object> > field,
                                                                     Expression <Func <TForeign, object> > foreignField,
                                                                     OnFkOption onUpdate,
                                                                     OnFkOption onDelete,
                                                                     string foreignKeyName = null)
        {
            var sourceMD  = ModelDefinition <T> .Definition;
            var fieldName = sourceMD.GetFieldDefinition(field).FieldName;

            var referenceMD        = ModelDefinition <TForeign> .Definition;
            var referenceFieldName = referenceMD.GetFieldDefinition(foreignField).FieldName;

            string name = GetQuotedName(foreignKeyName.IsNullOrEmpty() ?
                                        "fk_" + sourceMD.ModelName + "_" + fieldName + "_" + referenceFieldName :
                                        foreignKeyName);

            return(string.Format("ALTER TABLE {0} ADD CONSTRAINT {1} FOREIGN KEY ({2}) REFERENCES {3} ({4}){5}{6};",
                                 GetQuotedTableName(sourceMD.ModelName),
                                 name,
                                 GetQuotedColumnName(fieldName),
                                 GetQuotedTableName(referenceMD.ModelName),
                                 GetQuotedColumnName(referenceFieldName),
                                 GetForeignKeyOnDeleteClause(new ForeignKeyConstraint(typeof(T), onDelete: FkOptionToString(onDelete))),
                                 GetForeignKeyOnUpdateClause(new ForeignKeyConstraint(typeof(T), onUpdate: FkOptionToString(onUpdate)))));
        }
        public virtual string  ToAddForeignKeyStatement <T, TForeign>(Expression <Func <T, object> > field,
                                                                      Expression <Func <TForeign, object> > foreignField,
                                                                      OnFkOption onUpdate,
                                                                      OnFkOption onDelete,
                                                                      string foreignKeyName = null)
        {
            var sourceMD = ModelDefinition <T> .Definition;

            var fname     = FieldName(field);
            var fieldName = sourceMD.FieldDefinitions.First(f => f.Name == fname).FieldName;

            var referenceMD = ModelDefinition <TForeign> .Definition;

            fname = FieldName(foreignField);
            var referenceFieldName = referenceMD.FieldDefinitions.First(f => f.Name == fname).FieldName;

            string name = GetQuotedName(foreignKeyName.IsNullOrEmpty()?
                                        "fk_" + sourceMD.ModelName + "_" + fieldName + "_" + referenceFieldName:
                                        foreignKeyName);

            return(string.Format("ALTER TABLE {0} ADD CONSTRAINT {1} FOREIGN KEY ({2}) REFERENCES {3} ({4}) ON UPDATE {5} ON DELETE {6};",
                                 GetQuotedTableName(sourceMD.ModelName),
                                 name,
                                 GetQuotedColumnName(fieldName),
                                 GetQuotedTableName(referenceMD.ModelName),
                                 GetQuotedColumnName(referenceFieldName),
                                 FkOptionToString(onUpdate),
                                 FkOptionToString(onDelete)));
        }
        public static void AddForeignKey <T, TForeign>(this IDbConnection dbConn,
                                                       Expression <Func <T, object> > field,
                                                       Expression <Func <TForeign, object> > foreignField,
                                                       OnFkOption onUpdate,
                                                       OnFkOption onDelete,
                                                       string foreignKeyName = null)
        {
            var command = dbConn.GetDialectProvider().ToAddForeignKeyStatement(
                field, foreignField, onUpdate, onDelete, foreignKeyName);

            dbConn.ExecuteSql(command);
        }
        protected string FkOptionToString(OnFkOption option)
        {
            switch (option)
            {
            case OnFkOption.Cascade: return("CASCADE");

            case OnFkOption.NoAction: return("NO ACTION");

            case OnFkOption.Restrict: return("RESTRICT");

            case OnFkOption.SetNull: return("SET NULL");

            default: return("RESTRICT");
            }
        }
        public static void AddForeignKey <T, TForeign>(this IDbCommand dbCmdm,
                                                       Expression <Func <T, object> > field,
                                                       Expression <Func <TForeign, object> > foreignField,
                                                       OnFkOption onUpdate,
                                                       OnFkOption onDelete,
                                                       string foreignKeyName = null)
        {
            string command = OrmLiteConfig.DialectProvider.ToAddForeignKeyStatement(field,
                                                                                    foreignField,
                                                                                    onUpdate,
                                                                                    onDelete,
                                                                                    foreignKeyName);

            dbCmdm.ExecuteSql(command);
        }
        /// <summary>Converts this object to an add foreign key statement.</summary>
        /// <typeparam name="T">       Generic type parameter.</typeparam>
        /// <typeparam name="TForeign">Type of the foreign.</typeparam>
        /// <param name="field">         The field.</param>
        /// <param name="foreignField">  The foreign field.</param>
        /// <param name="onUpdate">      The on update.</param>
        /// <param name="onDelete">      The on delete.</param>
        /// <param name="foreignKeyName">Name of the foreign key.</param>
        /// <returns>The given data converted to a string.</returns>
        public virtual string ToAddForeignKeyStatement <T, TForeign>(Expression <Func <T, object> > field,
                                                                     Expression <Func <TForeign, object> > foreignField,
                                                                     OnFkOption onUpdate,
                                                                     OnFkOption onDelete,
                                                                     string foreignKeyName = null)
        {
            var sourceMd  = ModelDefinition <T> .Definition;
            var fieldName = sourceMd.GetFieldDefinition(field).FieldName;

            var referenceMd        = ModelDefinition <TForeign> .Definition;
            var referenceFieldName = referenceMd.GetFieldDefinition(foreignField).FieldName;

            var name = GetQuotedName(string.IsNullOrEmpty(foreignKeyName)
                ? "fk_" + sourceMd.ModelName + "_" + fieldName + "_" + referenceFieldName
                : foreignKeyName);

            return($"ALTER TABLE {GetQuotedTableName(sourceMd.ModelName)} " +
                   $"ADD CONSTRAINT {name} FOREIGN KEY ({GetQuotedColumnName(fieldName)}) " +
                   $"REFERENCES {GetQuotedTableName(referenceMd.ModelName)} ({GetQuotedColumnName(referenceFieldName)})" +
                   $"{GetForeignKeyOnDeleteClause(new ForeignKeyConstraint(typeof(T), FkOptionToString(onDelete)))}" +
                   $"{GetForeignKeyOnUpdateClause(new ForeignKeyConstraint(typeof(T), onUpdate: FkOptionToString(onUpdate)))};");
        }