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
Naming convention not applied to tables in ASP.NET Identity #2
Comments
Apologies, I was accidentally not subscribed to notifications on this repo. I cannot reproduce this issue, can you please submit precise steps which reproduce the problem? Here's what I did: Starting program: class Program
{
static async Task Main(string[] args)
{
using var ctx = new BlogContext();
ctx.Database.EnsureDeleted();
ctx.Database.EnsureCreated();
}
}
public class BlogContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseNpgsql("...");
}
}
public class Blog
{
public int Id { get; set; }
public string Name { get; set; }
} I created a migration, then added |
Hi @roji, I don't know if @kanonlemon encountered exactly the same issue as me, but in my case the Identity Core tables were problematic - columns were snake_case, but table names remained CamelCase. I was able to fix this by configuring the model - using just |
I'm experiencing the same thing. In my case I'm using dotnet core 3.1 and trying to generate the migrations for Identity Server 4 PersistedGrantDbContext and ConfigurationDbContext. I'll try to pair it down to a simple example that illustrates the issue. Here is the code that is generated for one of the tables for instance:
|
That would be great. |
tl;dr The problem is specific to the ASP.NET Identity model. Because the model uses generic types (TUser, TRole...), it explicitly configures table names in OnModelCreating. Anything that happens in OnModelCreating takes precedence over conventions, which is what this plugin sets up to apply the naming. In other words, the mechanism of specifying table names in OnModelConfiguring was originally meant to allow users to override conventions, but in this case is being used by ASP.NET Identity in another way. @ajcvickers @AndriySvyryd any ideas here? Identity could have its own convention to set the names, but then we'd have two competing conventions with no clear ordering... |
@roji The ASP.NET Core Identity model is heavily configured--very few conventions are used in its configuration. It's seems pretty complicated to try to go back to using some conventions after this--it's not something I think you can do now. Even if we did, it would be work and a breaking change for Identity to opt into it, which I don't think will happen. |
That's what I thought. I'll close this for now... |
Note to anyone hitting this: although the plugin can't apply its naming conventions, you can do this yourself by dropping the following into your OnModelCreating: modelBuilder.Entity<IdentityUser>().ToTable("asp_net_users");
modelBuilder.Entity<IdentityUserToken<string>>().ToTable("asp_net_user_tokens");
modelBuilder.Entity<IdentityUserLogin<string>>().ToTable("asp_net_user_logins");
modelBuilder.Entity<IdentityUserClaim<string>>().ToTable("asp_net_user_claims");
modelBuilder.Entity<IdentityRole>().ToTable("asp_net_roles");
modelBuilder.Entity<IdentityUserRole<string>>().ToTable("asp_net_user_roles");
modelBuilder.Entity<IdentityRoleClaim<string>>().ToTable("asp_net_role_claims"); (don't forget to change |
to make the above compile I needed to add .HasNoKey() to each line. This did help with those tables, thank you. However; I seem to have a different situation where NO tables are getting the lower-case treatment. I do have the project broken across several projects with data, infrastructure, front-end. The front end is where something like dotnet ef database migration would be called. When I implement this code I get lowercase "properties" across the board and zero lowercase table names, any guesses? |
You should definitely not be adding HasNoKey() to the above - are you sure you're using Re the 2nd problem - are you saying you're seeing a non-Identity table not being affected by this plugin? If so, can you please open a new issue with a minimal code sample? |
Unfortunately, this not work anymore. I trying this: Startup.cs
ApplicationDbContext.cs
csproj With:
|
@igorgomeslima when you do ToTable, you're explicitly setting table names - EFCore.NamingConventions has nothing to do with anything at that point... Can you please double-check that there's actually a behavioral difference between 5.0.0 and a previous version? |
@roji With previous versions 5.0.0-preview8 & 5.0.0-preview5 i got the same result. With versions below those, I got the error mentioned here. At this point: "...(don't forget to change string if you're using another key type)..." if we change the type, for example, |
My point is that whatever is happening with ToTable is unrelated to this plugin - you should be able to remove EFCore.NamingConventions and see exactly the same behavior as you see with it. |
Yes. If remove the plugin call, the result is the same. So I mentioned, this configuration not work. |
Try posting that on the ASP.NET repo - this repo is for EFCore.NamingConventions. |
Would be nice to specify which tables need snake_case naming, for example I may want to use default naming for AspNetCore.Identity tables but snake_case for my own. The reason for it is the strange bug:
For now I deleted EFCore.NamingConventions and manually change column names. Update: solved the issue using dynamic model configuration: public class SnakeDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, int>
{
public DbSet<Reward> Rewards => Set<Reward>();
public DbSet<Education> Educations => Set<Education>();
public DbSet<Citizenship> Citizenships => Set<Citizenship>();
public DbSet<Position> Positions => Set<Position>();
public DbSet<RewardApplication> RewardApplications => Set<RewardApplication>();
public DbSet<Entity> Entities => Set<Entity>();
public DbSet<Person> People => Set<Person>();
public DbSet<Citizen> Citizens => Set<Citizen>();
public DbSet<Mother> Mothers => Set<Mother>();
public DbSet<Foreign> Foreigners => Set<Foreign>();
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
var entities = builder.Model.GetEntityTypes();
foreach (var entity in entities)
{
// Cannot invoke .ToTable for abstract classes when using TPC
// BaseEntity is the base class for user defined classes, does not change AspNetCore.Identity tables
if (!typeof(BaseEntity).IsAssignableFrom(entity.ClrType) || entity.IsAbstract())
{
continue;
}
// returns name of DbSet<TEntity> instead of TEntity
var currentTableName = builder.Entity(entity.Name).Metadata.GetTableName();
if (string.IsNullOrEmpty(currentTableName))
{
continue;
}
builder.Entity(entity.Name).ToTable(GetSnakeName(currentTableName));
foreach (var property in entity.GetProperties())
{
builder.Entity(entity.Name).Property(property.Name).HasColumnName(GetSnakeName(property.Name));
}
}
}
private string GetSnakeName(string name)
{
return string.Concat(
name.Select((x, i) => i > 0 && char.IsUpper(x)
? $"_{x}"
: x.ToString())).ToLower();
}
} |
.net3.0 core
in my code
the result of Migrations shows:
all columns have changed to snaked mode
but table names keep the CamelCase
The text was updated successfully, but these errors were encountered: