Custom HistoryContext not working

Discussion of open issues, suggestions and bugs regarding ADO.NET provider for PostgreSQL
Post Reply
dresel
Posts: 18
Joined: Tue 20 Nov 2012 13:38

Custom HistoryContext not working

Post by dresel » Wed 25 Jun 2014 14:09

Hi,

I'm trying to setup a custom HistoryContext (http://msdn.microsoft.com/en-us/data/dn456841.aspx) - I want the migration table to be lower case:

PgSqlHistoryContext.cs

Code: Select all

public class PgSqlHistoryContext : HistoryContext
{
	public PgSqlHistoryContext(DbConnection dbConnection, string defaultSchema)
		: base(dbConnection, defaultSchema)
	{
	}

	protected override void OnModelCreating(DbModelBuilder modelBuilder)
	{
		base.OnModelCreating(modelBuilder);

		modelBuilder.Entity<HistoryRow>().ToTable("__migration_history");

		modelBuilder.Entity<HistoryRow>().Property(entity => entity.MigrationId).HasColumnName("migration_id");
		modelBuilder.Entity<HistoryRow>().Property(entity => entity.ContextKey).HasColumnName("context_key");
		modelBuilder.Entity<HistoryRow>().Property(entity => entity.Model).HasColumnName("model");
		modelBuilder.Entity<HistoryRow>().Property(entity => entity.ProductVersion).HasColumnName("product_version");
	}
}
Configuration.cs

Code: Select all

public class Configuration : DbMigrationsConfiguration<PortalContext>
{
	public Configuration()
	{
		AutomaticMigrationsEnabled = true;

		SetSqlGenerator(PgSqlConnectionInfo.InvariantName, new PgSqlEntityMigrationSqlGenerator());
		SetHistoryContextFactory("Devart.Data.PostgreSql",
			(connection, defaultSchema) => new PgSqlHistoryContext(connection, defaultSchema));
	}

	protected override void Seed(PortalContext context)
	{
	}
}
Is this supported?

Shalex
Site Admin
Posts: 9543
Joined: Thu 14 Aug 2008 12:44

Re: Custom HistoryContext not working

Post by Shalex » Thu 26 Jun 2014 06:56

Please try this code.

App.config:

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name="PortalContext" connectionString="server=db;port=5441;database=my_database;uid=postgres;pwd=postgres;schema=public;" providerName="Devart.Data.PostgreSql" />
  </connectionStrings>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
      <provider invariantName="Devart.Data.PostgreSql" type="Devart.Data.PostgreSql.Entity.PgSqlEntityProviderServices, Devart.Data.PostgreSql.Entity, Version=7.3.190.6, Culture=neutral, PublicKeyToken=09af7300eec23701" />
    </providers>
  </entityFramework>
</configuration>
Program.cs:

Code: Select all

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

using System.Data.Common;
using System.Data.Entity.Migrations.History;
using System.Data.Entity.Migrations;
using Devart.Data.PostgreSql.Entity.Migrations;

namespace DevArtEFTest
{
    class Program
    {
        static void Main(string[] args)
        {

            var monitor = new Devart.Data.PostgreSql.PgSqlMonitor() { IsActive = true };

            Database.SetInitializer<PortalContext>(new DropCreateDatabaseAlways<PortalContext>());

            var drone = new Drone
            {
                Name = "Test Drone"
            };

            using (var ctx = new PortalContext())
            {
                ctx.Drones.Add(drone);
                ctx.SaveChanges();
            }

            if (System.Diagnostics.Debugger.IsAttached)
            {
                Console.Write("Any key to terminate... ");
                Console.ReadKey(true);
            }
        }
    }

    public class Drone
    {
        public int DroneId { get; set; }
        public string Name { get; set; }
    }

    public class PortalContext : DbContext
    {
        public DbSet<Drone> Drones { get; set; }
    }

    public class PgSqlHistoryContext : HistoryContext
    {
        public PgSqlHistoryContext(DbConnection dbConnection, string defaultSchema)
            : base(dbConnection, defaultSchema)
        {
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<HistoryRow>().ToTable("__migration_history");

            modelBuilder.Entity<HistoryRow>().Property(entity => entity.MigrationId).HasColumnName("migration_id");
            modelBuilder.Entity<HistoryRow>().Property(entity => entity.ContextKey).HasColumnName("context_key");
            modelBuilder.Entity<HistoryRow>().Property(entity => entity.Model).HasColumnName("model");
            modelBuilder.Entity<HistoryRow>().Property(entity => entity.ProductVersion).HasColumnName("product_version");
        }
    }

    public class Configuration : DbMigrationsConfiguration<PortalContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = true;

            SetSqlGenerator(PgSqlConnectionInfo.InvariantName, new PgSqlEntityMigrationSqlGenerator());
            SetHistoryContextFactory("Devart.Data.PostgreSql",
               (connection, defaultSchema) => new PgSqlHistoryContext(connection, defaultSchema));
        }

        protected override void Seed(PortalContext context)
        {
        }
    }
    
}

dresel
Posts: 18
Joined: Tue 20 Nov 2012 13:38

Re: Custom HistoryContext not working

Post by dresel » Mon 07 Jul 2014 08:06

This does work but uses DropCreateDatabaseAlways - in combination with System.Data.Entity.MigrateDatabaseToLatestVersion this will not work.

Do you want another sample for reproduction?

Shalex
Site Admin
Posts: 9543
Joined: Thu 14 Aug 2008 12:44

Re: Custom HistoryContext not working

Post by Shalex » Mon 07 Jul 2014 10:44

1. Is it enough to replace

Code: Select all

Database.SetInitializer<PortalContext>(new DropCreateDatabaseAlways<PortalContext>());
with

Code: Select all

Database.SetInitializer(new MigrateDatabaseToLatestVersion<PortalContext, Configuration>());
in our sample from the previous message for reproducing?

2. Specify the exact text of the error and its stack trace with all inner exceptions.

3. Tell us the exact versions of your:
a) EntityFramework package
b) dotConnect for PostgreSQL
c) both .NET Framework versions - installed on the workstation and used in the project

dresel
Posts: 18
Joined: Tue 20 Nov 2012 13:38

Re: Custom HistoryContext not working

Post by dresel » Mon 07 Jul 2014 11:23

1. Yes but I also had to set the connection (because I use a different connection now):

Code: Select all

	public PortalContext()
		: base("name=TestContext")
	{
	}
2. Exception Infos:

Code: Select all

Error: {Error: 42703: column "MigrationId" of relation "__migration_history" does not exist}
ErrorSql: INSERT INTO __migration_history ("MigrationId", "ContextKey", "Model", "ProductVersion") VALUES ('201407071107575_AutomaticMigration', 'DevArtEFTest.Configuration', E'\\SomeBinaryString', '6.1.1-30610')
Message: column "MigrationId" of relation "__migration_history" does not exist
StackTrace:    at Devart.Data.PostgreSql.ae.f(ac A_0)
   at Devart.Data.PostgreSql.ac.n()
   at Devart.Data.PostgreSql.PgSqlCommand.InternalPrepare(Boolean implicitPrepare, Int32 startRecord, Int32 maxRecords)
   at Devart.Common.DbCommandBase.ExecuteDbDataReader(CommandBehavior behavior, Boolean nonQuery)
   at Devart.Common.DbCommandBase.ExecuteDbDataReader(CommandBehavior behavior)
   at Devart.Common.DbCommandBase.ExecuteNonQuery()
   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<NonQuery>b__0(DbCommand t, DbCommandInterceptionContext`1 c)
   at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.NonQuery(DbCommand command, DbCommandInterceptionContext interceptionContext)
   at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteNonQuery()
   at System.Data.Entity.Migrations.DbMigrator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement, DbInterceptionContext interceptionContext)
   at System.Data.Entity.Migrations.Infrastructure.MigratorBase.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement, DbInterceptionContext interceptionContext)
   at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable`1 migrationStatements, DbTransaction transaction, DbInterceptionContext interceptionContext)
   at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable`1 migrationStatements, DbConnection connection)
   at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClass30.<ExecuteStatements>b__2e()
   at System.Data.Entity.Infrastructure.DefaultExecutionStrategy.Execute(Action operation)
   at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements, DbTransaction existingTransaction)
   at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements)
   at System.Data.Entity.Migrations.Infrastructure.MigratorBase.ExecuteStatements(IEnumerable`1 migrationStatements)
   at System.Data.Entity.Migrations.DbMigrator.ExecuteOperations(String migrationId, XDocument targetModel, IEnumerable`1 operations, IEnumerable`1 systemOperations, Boolean downgrading, Boolean auto)
   at System.Data.Entity.Migrations.DbMigrator.AutoMigrate(String migrationId, VersionedModel sourceModel, VersionedModel targetModel, Boolean downgrading)
   at System.Data.Entity.Migrations.Infrastructure.MigratorBase.AutoMigrate(String migrationId, VersionedModel sourceModel, VersionedModel targetModel, Boolean downgrading)
   at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
   at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
   at System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration)
   at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClassc.<Update>b__b()
   at System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
   at System.Data.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
   at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
   at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update()
   at System.Data.Entity.MigrateDatabaseToLatestVersion`2.InitializeDatabase(TContext context)
   at System.Data.Entity.Internal.InternalContext.<>c__DisplayClassf`1.<CreateInitializationAction>b__e()
   at System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action)
   at System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization()
   at System.Data.Entity.Internal.LazyInternalContext.<InitializeDatabase>b__4(InternalContext c)
   at System.Data.Entity.Internal.RetryAction`1.PerformAction(TInput input)
   at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(Action`1 action)
   at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase()
   at System.Data.Entity.Internal.InternalContext.Initialize()
   at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
   at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
   at System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext()
   at System.Data.Entity.Internal.Linq.InternalSet`1.ActOnSet(Action action, EntityState newState, Object entity, String methodName)
   at System.Data.Entity.Internal.Linq.InternalSet`1.Add(Object entity)
   at System.Data.Entity.DbSet`1.Add(TEntity entity)
   at DevArtEFTest.Program.Main(String[] args) in c:\Users\Christopher\Documents\Visual Studio 2013\Projects\LacoWikiLive\Source\ConsoleApplication1\ConsoleApplication1\Program.cs:line 33
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()
I'm using Devart dotConnect for PostgreSQL Trial 7.3.181.0 (Devart.Data.PostgresSql.Entity shows 7.3.181.6) with EntityFramework 6.1.1 and PostgreSQL 9.3.

Installed .NET Framework: .NET Framework 4.5.1 installed with Windows 8.1 (4.5.51641)
Target framework: .NET Framework 4.5.1 (also tried it with 4.0)

Shalex
Site Admin
Posts: 9543
Joined: Thu 14 Aug 2008 12:44

Re: Custom HistoryContext not working

Post by Shalex » Tue 08 Jul 2014 12:42

Thank you for your report. We have reproduced the issue. We will investigate it and notify you about the result.

dresel
Posts: 18
Joined: Tue 20 Nov 2012 13:38

Re: Custom HistoryContext not working

Post by dresel » Thu 24 Jul 2014 07:47

Any updates on this issue yet?

Best Regards,
Dresel

Shalex
Site Admin
Posts: 9543
Joined: Thu 14 Aug 2008 12:44

Re: Custom HistoryContext not working

Post by Shalex » Fri 25 Jul 2014 10:00

The investigation is in progress. We will notify you about the results as any are available.

Shalex
Site Admin
Posts: 9543
Joined: Thu 14 Aug 2008 12:44

Re: Custom HistoryContext not working

Post by Shalex » Thu 31 Jul 2014 08:21

The bug with applying custom HistoryContext settings is fixed. We will notify you when the corresponding build of dotConnect for PostgreSQL is available for download.

Please take into account the following information: we do not recommend to rename __MigrationHistory because this may cause problems.

Shalex
Site Admin
Posts: 9543
Joined: Thu 14 Aug 2008 12:44

Re: Custom HistoryContext not working

Post by Shalex » Thu 31 Jul 2014 16:01

New build of dotConnect for PostgreSQL 7.3.215 is available for download!
It can be downloaded from http://www.devart.com/dotconnect/postgr ... nload.html (trial version) or from Registered Users' Area (for users with active subscription only).
For more information, please refer to http://forums.devart.com/viewtopic.php?f=3&t=30076.

Post Reply