0

ここで述べたように、Entity Framework Code First - Firebird migration: No MigrationSqlGenerator? Firebird データベースで移行を有効にしようとしています。

そのために、「MigrationSqlGenerator」の次の実装を作成しています (まだ完成していません!)。

public class FirebirdMigrationSQLGenerator : SqlServerMigrationSqlGenerator
{
    protected override DbConnection CreateConnection()
    {
        return DbProviderFactories.GetFactory("FirebirdSql.Data.FirebirdClient").CreateConnection();
    }

    protected override void Generate(CreateTableOperation createTableOperation)
    {
        using (var writer = Writer())
        {
            WriteCreateTable(createTableOperation, writer);

            Statement(writer.InnerWriter.ToString(), true);
        }
    }

    private void WriteCreateTable(CreateTableOperation createTableOperation, IndentedTextWriter writer)
    {
        writer.WriteLine("CREATE TABLE " + Name(createTableOperation.Name) + " (");
        writer.Indent++;

        var columnCount = createTableOperation.Columns.Count();

        createTableOperation.Columns.Each(
            (c, i) =>
            {
                Generate(c, writer);

                if (i < columnCount - 1)
                {
                    writer.WriteLine(",");
                }
            });

        if (createTableOperation.PrimaryKey != null)
        {
            writer.Write(", PRIMARY KEY ");

            writer.Write("(");
            writer.Write(createTableOperation.PrimaryKey.Columns.Join(Quote));
            writer.WriteLine(")");
        }
        else
        {
            writer.WriteLine();
        }

        writer.Indent--;
        writer.Write(")");
    }

    private void Generate(ColumnModel column, IndentedTextWriter writer)
    {

        writer.Write(Quote(column.Name));
        writer.Write(" ");
        writer.Write(BuildColumnType(column));

        if ((column.IsNullable != null)
            && !column.IsNullable.Value)
        {
            writer.Write(" NOT NULL");
        }

        if (column.DefaultValue != null)
        {
            writer.Write(" DEFAULT ");
            writer.Write(Generate((dynamic)column.DefaultValue));
        }
        else if (!string.IsNullOrWhiteSpace(column.DefaultValueSql))
        {
            writer.Write(" DEFAULT ");
            writer.Write(column.DefaultValueSql);
        }
    }

    protected override void Generate(InsertHistoryOperation op)
    {
        using (var writer = Writer())
        {
            WriteinsertHistory(op, writer);
            Statement(writer.InnerWriter.ToString(), true);
        }

    }

    private void WriteinsertHistory(InsertHistoryOperation insertHistoryOperation, IndentedTextWriter writer)
    {
        StringBuilder model = new StringBuilder();

        foreach (byte item in insertHistoryOperation.Model)
            model.Append(item.ToString("X2"));

        writer.Write("INSERT INTO \"" + insertHistoryOperation.Table.ToUpper() + "\" (migrationId, model, productVersion) ");
        writer.Write(" values ( '{0}', '{1}', '{2}') ",
                          insertHistoryOperation.MigrationId,
                  "0x" + model.ToString(),
                  insertHistoryOperation.ProductVersion);

    }

    protected override string Quote(string identifier)
    {
        return identifier.Replace("PK_dbo.", "").ToUpper();
    }

    protected override string Name(string inString)
    {
        return "\"" + inString.Replace("dbo.", "").ToUpper() + "\"";
    }

    protected override string BuildColumnType(ColumnModel column)
    {
        String colType = base.BuildColumnType(column);
        if (colType == "INT")
            colType = "INTEGER";
        return colType;
    }
}

私の問題は、__MigrationHistory テーブルが大文字で作成されることです。しかし、「HistoryContext」はそうではないため、最初の SELECT ステートメントは例外をスローしています。

SELECT 
"A"."A1" AS "C1"
FROM ( SELECT 
COUNT("B"."A1") AS "A1"
FROM ( SELECT 
    1 AS "A1"
    FROM "__MigrationHistory" AS "B"
)  AS "B"
)  AS "A"

通常、「modelBuilder.Conventions.Remove()」をコンテキストに挿入しますが、HistroyContext はフレームワークの一部であり、変更できません...

何か案は?私の環境: EntityFramework 5.0.0 .NET 4.5 FirebirdClient 3.0.2.0

4

1 に答える 1

1

Firebird では、テーブル名は引用された場合にのみ大文字と小文字が区別されるため、(作成時とクエリの両方で) テーブル名の引用を停止するか、大文字のテーブル名を停止してそのまま使用する必要があります。

たとえば、 を発行すると、を使用してアクセスできるCREATE TABLE xyz ( ... )テーブルが作成されますが、およびも使用できます。を使用してアクセスすることはできません。XYZSELECT * FROM xyzXyZXYZ"XYZ""xyz"

テーブルを作成する as CREATE TABLE "xyz" ( ... )wil create a tablexyzを使用してのみアクセスできますSELECT * FROM "xyz"が、xyz(引用符なし) またはその他の大文字と小文字の組み合わせおよび引用符の有無にかかわらずアクセスすることはできません。一方、 と を使用してCREATE TABLE "XYZ" ( ... )アクセスすることはできますが、 を使用することはできません。SELECT * FROM xyz"XYZ"SELECT * FROM "xyz"

あなたのコードからわかる限り、引用符で囲まれていないテーブルを作成しているWriteCreateTableため、名前は大文字で保存されますが、引用符で挿入しています。Quoteまた、 andメソッドの契約/期待を調べることもNameできます.実装が逆になっているように見えるので(QuoteすべきことNameを実行し、その逆も同様です)。

于 2013-07-27T08:21:52.070 に答える