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

Custom types (enums) aren't available right after creation #2815

Closed
toxsedyshev opened this issue Jul 19, 2023 · 5 comments
Closed

Custom types (enums) aren't available right after creation #2815

toxsedyshev opened this issue Jul 19, 2023 · 5 comments

Comments

@toxsedyshev
Copy link

STR:

  1. Run the app with empty DB.
  2. Run initial migration that creates DB with custom types (enums).
  3. Try to seed DB inserting some rows with that custom types (enums).
  4. Exception is thrown:
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while saving the entity changes. See the inner exception for details.
System.ArgumentException: A PostgreSQL type with the name 'my_enum_type' was not found in the database
  1. Restart the app.
  2. DB is successfully seeded.

The issue: an absence of that new types in NpgsqlDatabaseInfo.ByName/ByFullName Dictionaries.

Workaround:
To reload types right after migration:

if (Database.GetDbConnection() is NpgsqlConnection npgsqlConnection)
{
    await npgsqlConnection.OpenAsync(token);
    await npgsqlConnection.ReloadTypesAsync();
    await npgsqlConnection.CloseAsync();
}
@roji
Copy link
Member

roji commented Jul 19, 2023

This is explicitly called out in the documentation.

@toxsedyshev
Copy link
Author

Oh, really. It least, somebody (who is as attentive as me) can google the solution now :)

@toxsedyshev
Copy link
Author

Tried the code from the docs:

using (var conn = (NpgsqlConnection)context.Database.GetDbConnection())
{
    conn.Open();
    conn.ReloadTypes();
}

... where connection is disposed instead of just closing (that doesn't always close the connection, but releases it in case it's pooled).
Tried seeding right after that and got System.ObjectDisposedException: Cannot access a disposed object. Object name: 'NpgsqlConnection'.
So, "official" version requires explicit creation of new connection after itself.

Btw, is there a reason to reload types manually? Why EF can't just do that inside Migrate() in case some types-related migration was applied?

PS. This is for another topic, but... Enums mapping is too complicated, requires duplication (MapEnum() + UseEnum()), explicit schema declaration (in case it's not public) using different contracts in that methods (fullname vs schema+name). Yes, I understand that it's not all efcore.pg, but also ngpsql. But working with enums isn't developer-friendly. Just to seed some thoughts to optimize it someday :)

@toxsedyshev toxsedyshev reopened this Jul 19, 2023
@roji
Copy link
Member

roji commented Jul 19, 2023

So, "official" version requires explicit creation of new connection after itself.

Yeah, makes sense - it should do Close (in a finally) instead of using to avoid this. Interested in submitting a doc PR to fix that (that's in https://github.com/npgsql/doc)?

Why EF can't just do that inside Migrate() in case some types-related migration was applied?

This really is a very PostgreSQL-specific need, and there's currently no EF extension hook for doing something after applying all migrations. In any case, applying migrations from inside your application is discouraged for most scenarios (see these docs), and this problem affects only that method. I'd recommend looking at more robust ways of applying migrations, such as migration bundles.

Enums mapping is too complicated [...]

Yeah, you're absolutely right - and a lot of the complexity indeed comes from the support being spread across both EF and Npgsql. For the duplication side, I have some thoughts in #2542 which would help; there's also #1026 which is older but may still be relevant.

I definitely agree this should improve, but it hasn't been high-priority enough up to now...

@roji
Copy link
Member

roji commented Jul 19, 2023

Thanks for the doc update @toxsedyshev!

@roji roji closed this as not planned Won't fix, can't repro, duplicate, stale Jul 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants