SubSonic 2 迁移插件:创建 MySQL 特定的外键迁移步骤

发布于 2024-07-25 11:59:16 字数 377 浏览 2 评论 0原文

我经常使用迁移(仅 MySQL),并且由于 SubSonic Migrations 只允许在 CreateForeignKey 中定义父列和主列,因此我无法在 FK 关系中定义更新/删除操作。

然而,有很多场景,例如,我需要定义一个 FK 关系,如果我删除父记录,则子表中的所有记录都应设置为 null(默认是限制删除)。

我使用一个小函数来为我做到这一点。 然而,由于这完全是 MySQL 特定的,并且它打破了迁移之前的想法(独立于数据库),因此我决定不为此提供补丁。 所以我在这里发布代码片段。

但如果有人也需要这个。 请随意使用它。
只有一个缺点:由于 sonic.exe 会读取代码文件并即时进行编译,因此您必须将代码粘贴到使用它的每个迁移中。

I use migrations a lot (only MySQL) and since SubSonic Migrations only allows to define the parent and the master column in CreateForeignKey, I cannot define the update/delete actions in a FK Relation.

However there a quite a number of scenarios where I, for instance, need to define a FK relation where, if I delete the parent record, all records in the child table should be set to null (default would be to restrict the delete).

I use a little function that does this for me.
However since this is totally MySQL specific, and it breaks the idea that stands behand migrations (to be DB independent), I decided not to provide a patch for this. So I post the code snippet here.

But if someone needs this, too. Feel free to use it.
There is only one drawback: Since sonic.exe reads the code file and complies it on the fly you have to paste the code into every migration where you use it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

淡淡離愁欲言轉身 2024-08-01 11:59:16

这是我使用它的示例迁移。
在 down 方法中,您可以仅使用现有的“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

    }

}

Here's a sample migration where I use this.
In the down method you can just use the existing "DropForeignKey(...)" method, since the naming stays the same.

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

    }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文