SQLite的entity frameworkMigrationSqlGenerator

是否有一个MigrationSqlGenerator for SQLite用于entity framework? 我只发现一个来自devart的商业广告。

找不到提供程序’System.Data.SQLite’的MigrationSqlGenerator。 使用目标迁移配置类中的SetSqlGenerator方法注册其他SQL生成器。

这就是我所做的: http : //msdn.microsoft.com/en-gb/data/jj591621

虽然这个post已经开放了很长时间,但我会根据我们的朋友NSGaga出现的内容发布我要做的事情。

我设法根据为SQLCE开发的内容创建了一个类“MigrationSqLiteGenerator”。 该类的代码太大,更多可以在我的博客上下载。

在Google云端硬盘上: https : //drive.google.com/file/d/0B-NCqWnMQpBrQjkxMkxnVlRzb00/view?usp=sharing

这个课程只有基础,加上是改进的起点。

22.Mar.2017由@ shiva编辑 :这是代码内联,因此如果Google Drive链接再次中断,您仍然可以访问代码。 刚刚发现SO在答案post中有30,000字符的限制,所以我不得不删除代码中的注释。 这是超过32,000字符与评论:)

 // *-----------------------------------------------------------------* // * * // * CRIADO POR...: Julio C. Borges. * // * DATA.........: 19/07/2013. * // * MOTIVO.......: * // * * // *-----------------------------------------------------------------* using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Data.Common; using System.Data.Entity.Migrations.Model; using System.Data.Entity.Migrations.Sql; using System.Data.Metadata.Edm; using System.Data.SQLite; using System.Globalization; using System.IO; using System.Linq; using System.Text; namespace ICM_Conexao.SqLite.Classes { ///  /// MigrationSqLiteGenerator ///  public class MigrationSqLiteGenerator : MigrationSqlGenerator { #region Constantes private const string pstrDefaultDateTime = "yyyy-MM-dd hh:mm:ss"; private const int pintDefaultStringMaxLength = 255; private const int pintDefaultPrecisaoNumerica = 10; private const byte pbytDefaultPrecisaoTempo = 7; private const byte pintDefaultEscala = 0; //private const string pstrNomeTabelaMigration = "__MigrationHistory"; #endregion #region Instancias private DbProviderManifest pprovProviderManifest; private List plstComandos; private bool pblnGerouPrimaryKey; #endregion #region Método de Geração sobrescrito de MigratioSqlGenerator public override IEnumerable Generate( IEnumerable lstOperacoesMigrations, string strManifestoProvider) { plstComandos = new List(); InicializaServicosProvider(strManifestoProvider); GeraComandos(lstOperacoesMigrations); return plstComandos; } #endregion #region Métodos de geração dos comandos protected virtual void Generate(CreateTableOperation opeCriacaoTabela) { // Preferencialmente não iremos gerar a tabela de dados do Migration if (opeCriacaoTabela.Name.Contains("MigrationHistory")) return; using (var ltextWriter = TextWriter()) { GeraComandoCriacaoTabela(opeCriacaoTabela, ltextWriter); ComandoSQL(ltextWriter); } } protected virtual void Generate(AddForeignKeyOperation opeChaveEstrangeira) { // Inicialmente não havera a criação de chave estrangeira } protected virtual void Generate(DropForeignKeyOperation dropForeignKeyOperation) { // Inicalmente não haverá a criação de chave estrangeira } protected virtual void Generate(CreateIndexOperation opeCriacaoIndex) { using (var ltextWriter = TextWriter()) { ltextWriter.Write("CREATE "); if (opeCriacaoIndex.IsUnique) ltextWriter.Write(" UNIQUE "); ltextWriter.Write("INDEX "); ltextWriter.Write(opeCriacaoIndex.Name); ltextWriter.Write(" ON "); ltextWriter.Write(RemoveDBO(opeCriacaoIndex.Table)); ltextWriter.Write("("); for (int lintCount = 0; lintCount < opeCriacaoIndex.Columns.Count; lintCount++) { var lstrDadosColuna = opeCriacaoIndex.Columns[lintCount]; ltextWriter.Write(lstrDadosColuna); if (lintCount < opeCriacaoIndex.Columns.Count - 1) ltextWriter.WriteLine(","); } ltextWriter.Write(")"); ComandoSQL(ltextWriter); } } protected virtual void Generate(DropIndexOperation opeDropIndex) { using (var ltextWriter = TextWriter()) { ltextWriter.Write("DROP INDEX "); ltextWriter.Write(opeDropIndex.Name); ComandoSQL(ltextWriter); } } protected virtual void Generate(AddPrimaryKeyOperation opeAdicionaPrimaryKey) { using (var ltextWriter = TextWriter()) { ltextWriter.Write("ALTER TABLE "); ltextWriter.Write(RemoveDBO(opeAdicionaPrimaryKey.Table)); ltextWriter.Write(" ADD CONSTRAINT "); ltextWriter.Write(opeAdicionaPrimaryKey.Name); ltextWriter.Write(" PRIMARY KEY "); ltextWriter.Write("("); for (int li = 0; li < opeAdicionaPrimaryKey.Columns.Count; li++) { var lstrDadosColuna = opeAdicionaPrimaryKey.Columns[li]; ltextWriter.Write(lstrDadosColuna); if (li < opeAdicionaPrimaryKey.Columns.Count - 1) ltextWriter.WriteLine(","); } ltextWriter.Write(")"); ComandoSQL(ltextWriter); } } protected virtual void Generate(DropPrimaryKeyOperation opeDropPrimaryKey) { using (var ltextWriter = TextWriter()) { ltextWriter.Write("ALTER TABLE "); ltextWriter.Write(RemoveDBO(opeDropPrimaryKey.Table)); ltextWriter.Write(" DROP CONSTRAINT "); ltextWriter.Write(opeDropPrimaryKey.Name); ComandoSQL(ltextWriter); } } protected virtual void Generate(AddColumnOperation opeAdicionaColuna) { using (var ltextWriter = TextWriter()) { ltextWriter.Write("ALTER TABLE "); ltextWriter.Write(RemoveDBO(opeAdicionaColuna.Table)); ltextWriter.Write(" ADD "); var lcmColuna = opeAdicionaColuna.Column; Generate(lcmColuna, ltextWriter, null); if ((lcmColuna.IsNullable != null) && !lcmColuna.IsNullable.Value && (lcmColuna.DefaultValue == null) && (string.IsNullOrWhiteSpace(lcmColuna.DefaultValueSql)) && !lcmColuna.IsIdentity && !lcmColuna.IsTimestamp && !lcmColuna.StoreType.Equals("rowversion", StringComparison.InvariantCultureIgnoreCase) && !lcmColuna.StoreType.Equals("timestamp", StringComparison.InvariantCultureIgnoreCase)) { ltextWriter.Write(" DEFAULT "); if (lcmColuna.Type == PrimitiveTypeKind.DateTime) { ltextWriter.Write(Generate(DateTime.Parse("1900-01-01 00:00:00", CultureInfo.InvariantCulture))); } else { ltextWriter.Write(Generate((dynamic)lcmColuna.ClrDefaultValue)); } } ComandoSQL(ltextWriter); } } protected virtual void Generate(DropColumnOperation opeRemoveColuna) { using (var ltextWriter = TextWriter()) { ltextWriter.Write("ALTER TABLE "); ltextWriter.Write(RemoveDBO(opeRemoveColuna.Table)); ltextWriter.Write(" DROP COLUMN "); ltextWriter.Write(opeRemoveColuna.Name); ComandoSQL(ltextWriter); } } protected virtual void Generate(AlterColumnOperation opeAlteraColuna) { var lcmColuna = opeAlteraColuna.Column; using (var ltextWriter = TextWriter()) { ltextWriter.Write("ALTER TABLE "); ltextWriter.Write(RemoveDBO(opeAlteraColuna.Table)); ltextWriter.Write(" ALTER COLUMN "); ltextWriter.Write(lcmColuna.Name); ltextWriter.Write(" "); ltextWriter.Write(ConstruirTipoColuna(lcmColuna)); if ((lcmColuna.IsNullable != null) && !lcmColuna.IsNullable.Value) { ltextWriter.Write(" NOT NULL"); } ComandoSQL(ltextWriter); } if ((lcmColuna.DefaultValue == null) && string.IsNullOrWhiteSpace(lcmColuna.DefaultValueSql)) return; using (var ltextWriter = TextWriter()) { ltextWriter.Write("ALTER TABLE "); ltextWriter.Write(RemoveDBO(opeAlteraColuna.Table)); ltextWriter.Write(" ALTER COLUMN "); ltextWriter.Write(lcmColuna.Name); ltextWriter.Write(" DROP DEFAULT"); ComandoSQL(ltextWriter); } using (var ltextWriter = TextWriter()) { ltextWriter.Write("ALTER TABLE "); ltextWriter.Write(RemoveDBO(opeAlteraColuna.Table)); ltextWriter.Write(" ALTER COLUMN "); ltextWriter.Write(lcmColuna.Name); ltextWriter.Write(" SET DEFAULT "); ltextWriter.Write( (lcmColuna.DefaultValue != null) ? Generate((dynamic)lcmColuna.DefaultValue) : lcmColuna.DefaultValueSql ); ComandoSQL(ltextWriter); } } protected virtual void Generate(DropTableOperation opeDropTable) { using (var ltextWriter = TextWriter()) { ltextWriter.Write("DROP TABLE "); ltextWriter.Write(RemoveDBO(opeDropTable.Name)); ComandoSQL(ltextWriter); } } protected virtual void Generate(SqlOperation opeSQL) { ComandoSQL(opeSQL.Sql, opeSQL.SuppressTransaction); } protected virtual void Generate(RenameColumnOperation opeRenomearColuna) { // Inicialmente não suportada } protected virtual void Generate(RenameTableOperation opeRenameTable) { } protected virtual void Generate(MoveTableOperation opeMoveTable) { } private void Generate(ColumnModel cmDadosColuna, IndentedTextWriter textWriter, PrimaryKeyOperation opePrimaryKey) { textWriter.Write(cmDadosColuna.Name); textWriter.Write(" "); bool lblnEhPrimaryKey = false; if (opePrimaryKey != null) lblnEhPrimaryKey = opePrimaryKey.Columns.Contains(cmDadosColuna.Name); if (lblnEhPrimaryKey) { if ((cmDadosColuna.Type == PrimitiveTypeKind.Int16) || (cmDadosColuna.Type == PrimitiveTypeKind.Int32)) textWriter.Write(" INTEGER "); else textWriter.Write(ConstruirTipoColuna(cmDadosColuna)); if (cmDadosColuna.IsIdentity) { textWriter.Write(" PRIMARY KEY AUTOINCREMENT "); pblnGerouPrimaryKey = true; } } else { textWriter.Write(ConstruirTipoColuna(cmDadosColuna)); if ((cmDadosColuna.IsNullable != null) && !cmDadosColuna.IsNullable.Value) { textWriter.Write(" NOT NULL"); } if (cmDadosColuna.DefaultValue != null) { textWriter.Write(" DEFAULT "); textWriter.Write(Generate((dynamic)cmDadosColuna.DefaultValue)); } else if (!string.IsNullOrWhiteSpace(cmDadosColuna.DefaultValueSql)) { textWriter.Write(" DEFAULT "); textWriter.Write(cmDadosColuna.DefaultValueSql); } } } protected virtual void Generate(HistoryOperation opeHistorico) { // Foi removido, pois atualmente não usaremos o Migration //using (var ltextWriter = TextWriter()) //{ // if (opeHistorico is InsertHistoryOperation) // { // InsertHistoryOperation lhisOperacaoInsert = opeHistorico as InsertHistoryOperation; // ltextWriter.Write(" INSERT INTO "); // ltextWriter.Write(pstrNomeTabelaMigration); // ltextWriter.Write(" ( MigrationId, Model, ProductVersion) VALUES "); // ltextWriter.Write(string.Format(" ('{0}', {1}, '{2}')", // lhisOperacaoInsert.MigrationId, // Generate(lhisOperacaoInsert.Model), lhisOperacaoInsert.ProductVersion)); // } // else if (opeHistorico is DeleteHistoryOperation) // { // DeleteHistoryOperation lhisOperacaoInsert = opeHistorico as DeleteHistoryOperation; // ltextWriter.Write(" DELETE FROM "); // ltextWriter.Write(pstrNomeTabelaMigration); // ltextWriter.Write(string.Format(" WHERE MigrationId = '{0}'", // lhisOperacaoInsert.MigrationId)); // } // ComandoSQL(ltextWriter); //} } protected virtual string Generate(byte[] bytDefaultValue) { var lstrbHexString = new StringBuilder(); foreach (var lbtByte in bytDefaultValue) lstrbHexString.Append(lbtByte.ToString("X2", CultureInfo.InvariantCulture)); return "x'" + lstrbHexString + "'"; } protected virtual string Generate(bool blnDefaultValue) { return blnDefaultValue ? "1" : "0"; } protected virtual string Generate(DateTime dtmDefaultValue) { return "'" + dtmDefaultValue.ToString(pstrDefaultDateTime, CultureInfo.InvariantCulture) + "'"; } protected virtual string Generate(DateTimeOffset dtfDefaultValue) { return "'" + dtfDefaultValue.ToString(pstrDefaultDateTime, CultureInfo.InvariantCulture) + "'"; } protected virtual string Generate(Guid guidDefaultValue) { return "'" + guidDefaultValue + "'"; } protected virtual string Generate(string strDefaultValue) { return "'" + strDefaultValue + "'"; } protected virtual string Generate(TimeSpan tsDefaultValue) { return "'" + tsDefaultValue + "'"; } protected virtual string Generate(object objDefaultValue) { return string.Format(CultureInfo.InvariantCulture, "{0}", objDefaultValue); } #endregion #region Métodos auxiliares protected virtual string ConstruirTipoColuna(ColumnModel cmModeloColuna) { return cmModeloColuna.IsTimestamp ? "rowversion" : ConstruirTipoPropriedade(cmModeloColuna); } private string ConstruirTipoPropriedade(ColumnModel propModeloPropriedade) { var lstrOriginalStoreTypeName = propModeloPropriedade.StoreType; if (string.IsNullOrWhiteSpace(lstrOriginalStoreTypeName)) { var ltypeUsage = pprovProviderManifest.GetStoreType(propModeloPropriedade.TypeUsage).EdmType; lstrOriginalStoreTypeName = ltypeUsage.Name; } var lstrStoreTypeName = lstrOriginalStoreTypeName; const string lstrSufixoMax = "(max)"; if (lstrStoreTypeName.EndsWith(lstrSufixoMax, StringComparison.Ordinal)) lstrStoreTypeName = lstrStoreTypeName.Substring(0, lstrStoreTypeName.Length - lstrSufixoMax.Length) + lstrSufixoMax; switch (lstrOriginalStoreTypeName.ToLowerInvariant()) { case "decimal": case "numeric": lstrStoreTypeName += "(" + (propModeloPropriedade.Precision ?? pintDefaultPrecisaoNumerica) + ", " + (propModeloPropriedade.Scale ?? pintDefaultEscala) + ")"; break; case "datetime": case "time": lstrStoreTypeName += "(" + (propModeloPropriedade.Precision ?? pbytDefaultPrecisaoTempo) + ")"; break; case "blob": case "varchar2": case "varchar": case "char": case "nvarchar": case "nvarchar2": lstrStoreTypeName += "(" + (propModeloPropriedade.MaxLength ?? pintDefaultStringMaxLength) + ")"; break; } return lstrStoreTypeName; } protected void ComandoSQL(string strInstrucaoSQL, bool blnSuprimeTransacao = false) { plstComandos.Add(new MigrationStatement { Sql = strInstrucaoSQL, SuppressTransaction = blnSuprimeTransacao }); } protected void ComandoSQL(IndentedTextWriter writer) { ComandoSQL(writer.InnerWriter.ToString()); } protected static IndentedTextWriter TextWriter() { return new IndentedTextWriter(new StringWriter(CultureInfo.InvariantCulture)); } private static string RemoveDBO(string strTexto) { return strTexto.Replace("dbo.", string.Empty); } private void GeraComandos(IEnumerable lstOperacoesMigrations) { foreach (dynamic ldynOperacao in lstOperacoesMigrations) Generate(ldynOperacao); } private void InicializaServicosProvider(string strManifestoProvider) { using (var lconConexao = CreateConnection()) { pprovProviderManifest = DbProviderServices .GetProviderServices(lconConexao) .GetProviderManifest(strManifestoProvider); } } protected virtual DbConnection CreateConnection() { return new SQLiteConnection(); } private void GeraComandoCriacaoTabela(CreateTableOperation opeCriacaoTabela, IndentedTextWriter textWriter) { textWriter.WriteLine("CREATE TABLE " + RemoveDBO(opeCriacaoTabela.Name) + " ("); textWriter.Indent++; for (int i = 0; i < opeCriacaoTabela.Columns.Count; i++) { ColumnModel lcmDadosColuna = opeCriacaoTabela.Columns.ToList()[i]; Generate(lcmDadosColuna, textWriter, opeCriacaoTabela.PrimaryKey); if (i < opeCriacaoTabela.Columns.Count - 1) textWriter.WriteLine(","); } if ((opeCriacaoTabela.PrimaryKey != null) && !pblnGerouPrimaryKey) { textWriter.WriteLine(","); textWriter.Write("CONSTRAINT "); textWriter.Write(RemoveDBO(opeCriacaoTabela.PrimaryKey.Name)); textWriter.Write(" PRIMARY KEY "); textWriter.Write("("); for (int li = 0; li < opeCriacaoTabela.PrimaryKey.Columns.Count; li++) { var lstrNomeColuna = opeCriacaoTabela.PrimaryKey.Columns[li]; textWriter.Write(lstrNomeColuna); if (li < opeCriacaoTabela.PrimaryKey.Columns.Count - 1) textWriter.WriteLine(","); } textWriter.WriteLine(")"); } else { textWriter.WriteLine(); } textWriter.Indent--; textWriter.Write(")"); } #endregion } } 

对于正在寻找处理迁移的生成器的任何人,我在https://sqliteef6migrations.codeplex.com上找到了一个名为“System.Data.SQLite.EF6.Migrations”的nuget包。

安装软件包后,您需要对迁移配置方法进行以下更改。

  public Configuration() { AutomaticMigrationsEnabled = false; SetSqlGenerator("System.Data.SQLite", new SQLiteMigrationSqlGenerator()); } 

完整的类应该看起来像这样。

 namespace YourNamespace { using System.Data.Entity.Migrations; using System.Data.SQLite.EF6.Migrations; internal sealed class Configuration : DbMigrationsConfiguration { public Configuration() { AutomaticMigrationsEnabled = false; SetSqlGenerator("System.Data.SQLite", new SQLiteMigrationSqlGenerator()); } protected override void Seed(YourContext context) { // This method will be called after migrating to the latest version. } } } 

我认为我们可以使用相同的Android概念为SQLite创建一个简单的迁移引擎。 这篇文章显示了这个概念。 当然,我们没有任何工作的MigrationSqlGenerator,但这个概念是可靠的和有用的。

我不知道任何SQLite,但如果你试图创建一个像其他人建议的那样,你可以使用这个开源项目开始。 或者您可能会发现这本身就足够了?

http://www.codeproject.com/Articles/32977/Upgrade-framework-for-SQLite-databases