Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multiple contexts against the same db results in both trying to create __MigrationHistory #171

Open
divega opened this Issue Jan 14, 2017 · 7 comments

Comments

Projects
None yet
6 participants
@divega
Copy link
Member

divega commented Jan 14, 2017

From @MichaelMcKechnie on December 16, 2016 13:28

I have two DbContext subclasses for the two different contexts I want to use in my solution. Each is defined in their own project, with their own configuration class and contextKey.

With a new database, the second context throws an exception ("name is already used") because it tries to create the __MigrationHistory table - which already exists because it was created by the first context.

In System.Data.Entity.Migrations.History.HistoryRepository.QueryExists I see that the code first checks for any migrations that match the context key, then it checks for the existence of the __MigrationHistory table. Unfortunately, the second check doesn't happen because it's wrapped in an if (!_contextKeyColumnExists).

I think the if (!_contextKeyColumnExists) should be removed - the HistoryRepository.QueryExists() method should return true for a database that has a _MigrationHistory table but does not have any migrations in it yet.

See ~line 462 in ([https://github.com/aspnet/EntityFramework6/blob/master/src/EntityFramework/Migrations/History/HistoryRepository.cs]...)

    foreach (var schema in _schemas.Reverse())
    {
        using (var context = CreateContext(connection, schema))
        {
            _currentSchema = schema;
            _contextKeyColumnExists = true;

            // Do the context-key specific query first, since if it succeeds we can avoid
            // doing the more general query.
            try
            {
                using (new TransactionScope(TransactionScopeOption.Suppress))
                {
                    contextKey = contextKey.RestrictTo(_contextKeyMaxLength);

                    if (context.History.Count(hr => hr.ContextKey == contextKey) > 0)
                    {
                        return true;
                    }
                }
            }
            catch (EntityException)
            {
                _contextKeyColumnExists = false;
            }

            // If the context-key specific query failed, then try the general query to see
            // if there is a history table in this schema at all
            if (!_contextKeyColumnExists)
            {
                try
                {
                    using (new TransactionScope(TransactionScopeOption.Suppress))
                    {
                        context.History.Count();
                    }
                }
                catch (EntityException)
                {
                    _currentSchema = null;
                }
            }
        }
    }
}
finally
{
    DisposeConnection(connection);
}

return !string.IsNullOrWhiteSpace(_currentSchema);

Copied from original issue: aspnet/EntityFrameworkCore#7260

@divega

This comment has been minimized.

Copy link
Member Author

divega commented Jan 14, 2017

@MichaelMcKechnie would it be possible for you to provide a repro project?

@MichaelMcKechnie

This comment has been minimized.

Copy link

MichaelMcKechnie commented Jan 15, 2017

I can give it a shot, sure. Where would you like me to post it?

fyi in my own case I ended up creating a custom HistoryContext with a custom TableName for one DbContext - so my two database schemas are managed via two different migration history tables in the same single database.

@divega

This comment has been minimized.

Copy link
Member Author

divega commented Jan 17, 2017

@MichaelMcKechnie anything from attaching a zip file to point to a repository would work. If you cannot share it publically but would still want to share it with us for the purpose of debugging it you can use email. I have the same alias in my Microsoft email account.

@MichaelMcKechnie

This comment has been minimized.

Copy link

MichaelMcKechnie commented Jan 18, 2017

OK, the console app at https://github.com/MichaelMcKechnie/TwoDbContexts tries to create two DbContext subclasses in the same database, using different context keys. WHichever one goes first, succeeds. The console app is set to randomly choose one or the other to go first.

@odannyc

This comment has been minimized.

Copy link

odannyc commented Jul 9, 2018

Was this ever solved?
I'm having the same issue:

  • 2 Projects with 2 different dbcontexts
  • they both use the same schema "public" and they both save to the same connection/database
  • both have AutomaticMigrationsEnabled = false;
  • using postgresql

On a clean database -> Update-Database on the first project succeeds, on the second project it throws relation "__MigrationHistory" already exists exception

@NikolaR

This comment has been minimized.

Copy link

NikolaR commented Jan 23, 2019

It appears that this happens if schema used is not named dbo.
I have same situation using Oracle. Upon applying migrations EF checks for configured schema, but then also checks for __MigrationHistory in dbo schema, and this basically leads it to attempt to create it.

My workaround is:

  1. Create dbo user (in oracle user is roughly equivalent to schema)
  2. Create __MigrationHistory table in dbo user database
  3. Beyond applying migrations dbo schema is not used, nor are migrations tracked in dbo.__MigrationHistory

It would be really nice to fix couple of bugs and release a SP at least. This is really preventing any large enterprise application from being developed against Oracle.

@NikolaR

This comment has been minimized.

Copy link

NikolaR commented Jan 23, 2019

Actually, just found quite clean solution. Instead of workaround above, it's possible to set DefaultSchema for EF HistoryContext table. If set to correct schema, it will not go to dbo context.

More details I wrote here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.