как бы я позвонил / использовал Subsonic из приложения WinForms, развертываемого через clickonce (с Sqlite DB) - PullRequest
1 голос
/ 02 марта 2010

Справочная информация. Мне нужна структура / подход к управляемым обновлениям баз данных для приложения .NET Winforms, развертываемого на компьютерах пользователей с помощью clickonce deploy. Приложение использует базу данных sqlite.

Q1. Какой механизм использует Subsonic для запуска таких миграций на локальном ПК? например это будет MSBuild

Q2. Если для этого нужен инструмент, например, как мое приложение может запустить MsBuild? то есть как можно быть уверенным, по какому пути он установлен, что, если он не установлен, должен ли я включать MSBuild.exe в пакет clickonce, чтобы я точно знал, что он там есть?

Q3. Любые другие предложения о том, как использовать Subsonic в этом конкретном случае использования?

Q4. Любые комментарии о том, подойдет ли MigratorDotNet лучше? (если кто-то имел опыт работы с обоими)

В5. Могу ли я использовать простую среду миграции от Subonic и просто иметь набор файлов SQL для обновления / понижения? т. е. просто использовать платформу для проверки версии базы данных и сценариев для запуска и т. д.

1 Ответ

1 голос
/ 03 мая 2010

Ну, пост немного устарел, но, возможно, мои ответы все еще полезны.

Q1: SubSonic Migrations - это файлы кода, которые выполняются и выполняются во время выполнения субкомандором (sonic.exe), что означает, что файлы кода должны находиться на диске и должны следовать соглашению об именах 001_migration_name.cs, чтобы субкомандор знал порядок выполнения .

Q2: вам не нужен msbuild для миграции. Единственное, что вам нужно, это sonic.exe и его зависимости.

В3: Можно (и не очень сложно) создать собственный логик для выполнения миграций в вашем проекте во время выполнения без использования субкомандера.

Я в основном нахожу каждый класс, производный от Migration, и (поскольку класс не может начинаться с числа), мое соглашение заключается в том, что последние 3 цифры из имени класса являются номером миграции (например, 001_migration_name.cs, мои классы определены as Migration001: Миграция)

public class MigrationHelper
{
    private const string providerName = "MyProviderName";
    public static int CurrentVersion { get { return SubSonic.Migrations.Migrator.GetCurrentVersion(providerName); } }

    private static Dictionary<int, Migration> _migrations;
    public static Dictionary<int, Migration> Migrations
    {
        get
        {

            if (_migrations == null)
            {
                _migrations = new Dictionary<int, Migration>();
                foreach (Type t in new MigrationHelper().GetType().Assembly.GetExportedTypes())
                {
                    if (t.BaseType == typeof(SubSonic.Migration))
                    {
                        int number;
                        if (int.TryParse(t.Name.Substring(t.Name.Length - 3, 3), out number))
                            Migrations.Add(number, (Migration)Activator.CreateInstance(t));
                        else
                            throw new InvalidOperationException("Classes that inherit SubSonic Migrations have to be named MigrationXXX where x is the unique migration number");
                    }
                }
            }
            return _migrations;

        }
    }

    public static void ExecuteMigration(Migration m, Migration.MigrationDirection direction)
    {
        m.Migrate(providerName, direction);
    }


}

В вашей программе вы можете определить текущую версию с помощью MigrationHelper.CurrentVersion, а затем выполнить каждую миграцию от текущей к максимальной (если вы хотите подняться) или некоторого другого числа. Вот как вы это используете.

        Migration m = MigrationHelper.Migrations[15];
        MigrationHelper.ExecuteMigration(m, Migration.MigrationDirection.Up);

В4: У меня нет опыта работы с MigratorDotNet, но если ваше приложение использует дозвуковую среду, то дозвуковая миграция является хорошим выбором, поскольку вам не нужно развертывать какие-либо дополнительные библиотеки.

В5: Для этого вы можете использовать дозвуковые миграции. Просто сделайте:

Execute("CREATE TABLE ...");

в методе Up () или Down (). Но преимущество использования предопределенных методов заключается в том, что (помимо того, что они работают с несколькими базами данных, что не так важно, если вы используете только sqlite), у вас есть некоторые проверки перед полетом (например, миграция завершится неудачно, если вы определите поле дважды перед выполнением фактического sql)

...