-
Notifications
You must be signed in to change notification settings - Fork 225
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
Noda Time plugin compatibility with AspNet Core Identity & plugin not being registered in migration #526
Comments
@etiennemtl Are you explicitly registering the plugin when you configure services for DI? Could you post some code showing how you're configuring EF Core? |
Both issues likely have the same source. I'm assuming that you're seeding and attempting to create migrations from the command line tool ( Let me know if this helps you. |
Ah, just saw @austindrenski's response. Yes, if the above doc link doesn't help, try posting your context code etc. |
Hey my public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
private readonly IClock clock;
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, IClock clock)
: base(options)
{
this.clock = clock;
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Use the new identity columns added in Postgresql 10.0
builder.ForNpgsqlUseIdentityColumns();
// IMPORTANT
// Apply Postgresql naming conventions
foreach (var entity in builder.Model.GetEntityTypes())
{
// Replace table names
entity.Relational().TableName = entity.Relational().TableName.Pluralize().ToSnakeCase();
// Replace column names
foreach (var property in entity.GetProperties())
{
property.Relational().ColumnName = property.Name.ToSnakeCase();
}
foreach (var key in entity.GetKeys())
{
key.Relational().Name = key.Relational().Name.ToSnakeCase();
}
foreach (var key in entity.GetForeignKeys())
{
key.Relational().Name = key.Relational().Name.ToSnakeCase();
}
foreach (var index in entity.GetIndexes())
{
index.Relational().Name = index.Relational().Name.ToSnakeCase();
}
}
}
} Besides it lives my public class ApplicationDbContextDesignTimeFactory : IDesignTimeDbContextFactory<ApplicationDbContext>
{
public ApplicationDbContext CreateDbContext(string[] args)
{
var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
var connectionString = Environment.GetEnvironmentVariable("DATABASE_URL");
builder.UseNpgsql(connectionString, sql => sql.UseNodaTime());
return new ApplicationDbContext(builder.Options, SystemClock.Instance);
}
} In my web project, in public IServiceProvider ConfigureServices(IServiceCollection services)
{
var connectionString = Environment.GetEnvironmentVariable("DATABASE_URL");
services.AddDbContext<ApplicationDbContext>(options => options.UseNpgsql(connectionString, sql => sql.UseNodaTime()));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
} Here is an example command in order to add a migration
And to update the database
|
@austindrenski For your information I'm also using StructureMap in order to register my other services. When debugging the context, I see that the |
@etiennemtl Thanks for posting your context code. But looking at it, I'm still not sure what's happening. Could you put together a minimal reproduction that recreates the exception, preferably in the form of a repo that we can clone? |
@austindrenski I'm sorry for the late response, here is the repo https://github.com/etiennemtl/identity-npsql-nodatime. I've figured that the issue is when trying to configure multiple |
Sorry this issue hasn't received any attention recently. As far as seeding NodaTime values, this is a known issue that was blocked on the EF Core side. The good news is that EF Core 2.2 contains the necessary infrastructure, and "code literal generation" has already been merged to Npgsql for many types. Unfortunately, this hasn't yet been done for NodaTime, which presents a few more complexities - but I hope we can finish this for the upcoming 2.2 release. This is tracked by #667. In addition, EF Core implements a new plugin model in 2.2 (somewhat based on the one Npgsql introduced in 2.1), and the Npgsql provider has been changed to align with it (#658) - there's a good chance this would solve some of the issues you've been seeing. As this issue is old and the problems it discusses are currently being worked on, I'm going to go ahead and close this - but please feel free to post back here, especially after 2.2 comes out. |
Hi @roji, it has happened to me today when I was refactoring an Entity to move some of its Instant properties to another; db-related 1:1 entity. After I made the changes and set-up new Entity with all properties and relations in fluent syntax I wanted to add new migration. I was presented with: |
@roji due to my lack of deeper understanding of EF Core, Npgsql and NodaTime I was wondering what is going on. Why do we need literal generation for as basic operation as creating new Entity or changing an existing Entity? Thank You in advance. |
@Slaviusz unless I'm mistaken, literal generation should only be required for data seeding, which is not exactly a critical feature. If you're seeing this message without doing any data seeding, please let me know. |
@roji I do no data seeding whatsoever. Please have a look at the simplistic repo I have created on GitHub. It has 3 commits, first one creates one complex entity and the third one does split it into two by moving Instant properties away. By trying to do "dotnet ef migrations add Split" on last commit you get the error message. This is even without any data or seeding applied. |
I'll try looking at your repo and investigating deeper in the next couple of days. In the meantime, one sure workaround is to remove the existing migration and start from scratch. |
Hi @roji , What I figured out works is, if I split it to 2 migrations:
|
Workaround (remove previous migration) is working, however it would be quite annoying if I was already in prod; my previous migration is Initial which means that I must run dotnet ef database update 0 which drops the tables, and thus my data... Looking forward to resolution of #854! |
@Slaviusz I don't quite understand your steps. When you say Cast, do you mean, change the property type for string, or truly adding a new property (string) that "casts" the value of the Instant property? If so how should it be named, and how does that solve the problem? Thanks! |
On my side the problem arises when I add properties, not when I remove them; testing your workaround.
So far, this is working. However, when updating the database, I have the following error: Npgsql.PostgresException (0x80004005): 42804: column "date_updated" cannot be cast automatically to type timestamp without time zone |
@roji, do you have an ETA on version 3.0? |
Hey @invertedrider, Then PostgreSQL does someting along the lines of: Then of course the same column FaultyPropery is of type varchar and in the POCO the property FaultyProperty is of type string and dropping it in the next migration works. Hope that helps. Regards. |
@Slaviusz thanks for the quick response I've found in a related issue (#769, posted by @roji) that the problems lies in the fact that when the property is not nullable then EF Core asks for a litteral for the default value. Don't know why they would ask for it when removing a column; don't know either why it actually works on Initial migration; but your workaround is probably working because it has no problem going from Instant to string. Anyway, in issue #769, @roji mentions that all you have to do is declare your property as nullable (e.g. Instant?) which removes the need for the litteral (no need for a default value). That's for adding properties however; I don't know if removing those properties will work directly or will still need your workaround Take care |
I'm currently using versions 2.1 of your wonderful driver for EF Core and also using the NodaTime plugin in order to user enhance date/time classes. Basically I have two main issues.
The first one is it's currently not possible for me to seed data in the
Main
of the application as it seems the plugin is not being registered. I've got this error popping. I've able to add migration and update the database though.The second one is Iv'e inherited from
IdentityUser
in order to addCreatedAt
andUpdatedAt
properties of tipeInstant
but I'm unable to add a migration. It throws me this error:Although when using a
DateTime
, everything is working properly.I'm using version
Npgsql.EntityFrameworkCore.PostgreSQL 2.1.1.1
andNpgsql.EntityFrameworkCore.PostgreSQL.NodaTime 2.1.1
The text was updated successfully, but these errors were encountered: