SubSonic 2 Migrations Addon: Создайте специфичный для MySQL шаг ForeignKey Migrationstep

0

Я много использую миграции (только MySQL), и поскольку SubSonic Migrations позволяет определять родительский и главный столбцы в CreateForeignKey, я не могу определить действия по обновлению/удалению в FK Relation.

Однако существует довольно много сценариев, где мне, например, нужно определить отношение FK, где, если я удалю родительскую запись, все записи в дочерней таблице должны быть установлены в нуль (по умолчанию было бы ограничено удаление).

Я использую небольшую функцию, которая делает это для меня. Однако, поскольку это полностью зависит от MySQL, и это ломает идею, что стоит behand migrations (чтобы быть независимым от DB), я решил не предоставлять патч для этого. Поэтому я размещаю фрагмент кода здесь.

Но если кому-то это нужно, тоже. Не стесняйтесь использовать его.
Существует только один недостаток: поскольку sonic.exe считывает файл кода и выполняет его на лету, вам нужно вставить код в каждую миграцию, где вы его используете.

Теги:
migration
subsonic

1 ответ

0
Лучший ответ

Здесь пример миграции, где я использую это. В методе "вниз" вы можете просто использовать существующий метод "DropForeignKey (...)", поскольку именование остается прежним.

using System;
using System.Collections.Generic;
using System.Text;
using SubSonic;

namespace MyNameSpace.Migrations
{

    public class Migration001 : Migration
    {

        public override void Up()
        {
            TableSchema.Table parent = GetTable("parent");
            TableSchema.Table child = GetTable("child");

            CreateForeignKeyMySQL(parent.GetColumn("id"), child.GetColumn("parent_id"),
                CreateForeignKeyAction.SetNull, CreateForeignKeyAction.Restrict);

            base.Up();
        }

        public override void Down()
        {
            DropForeignKey(parent.GetColumn("id"), child.GetColumn("parent_id"));

            base.Down();
        }

        #region foreign key helper function

        public enum CreateForeignKeyAction
        {
            Cascade,
            Restrict,
            SetNull,
            NoAction
        }

        private String CreateForeignKeyActionValue(CreateForeignKeyAction action)
        {
            switch (action)
            {
                case CreateForeignKeyAction.Cascade:
                    return "CASCADE";
                case CreateForeignKeyAction.Restrict:
                    return "RESTRICT";
                case CreateForeignKeyAction.SetNull:
                    return "SET NULL";
                case CreateForeignKeyAction.NoAction:
                    return "NO ACTION";
                default:
                    return "CASCADE";
            }
        }

        public void CreateForeignKeyMySQL(
            TableSchema.TableColumn oneTable, TableSchema.TableColumn manyTable,
            CreateForeignKeyAction onDelete, CreateForeignKeyAction onUpdate)
        {

            String sqlAppend = String.Format(" ON DELETE {0} ON UPDATE {1}",
                CreateForeignKeyActionValue(onDelete), CreateForeignKeyActionValue(onUpdate));

            SubSonic.MySqlGenerator generator = new SubSonic.MySqlGenerator(null);
            String sqlCommand =
                System.Text.RegularExpressions.Regex.Replace(
                    generator.BuildForeignKeyStatement(oneTable, manyTable), ";?$", sqlAppend
                );

            Execute(sqlCommand);
        }

        #endregion

    }

}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню