正如这里提到的实体框架代码优先 - Firebird 迁移:没有 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