Is there a simple way to split ASP .Net Identity entities across multiple tables? I know you can change the name of the tables used by Identity using OnModelCreating.
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<IdentityUser>().ToTable("IdentityUser").Property(p => p.Id).HasColumnName("UserId");
}
Can you similarly use an override in OnModelCreating or elsewhere to split across multiple tables? I tried using a map:
modelBuilder.Entity<IdentityUser>().Map(m =>
{
m.Properties(t => new {t.Id, t.UserName});
m.ToTable("User");
});
but I receive an error indicating UserName is already mapped. The non-key property 'UserName' is mapped more than once. Ensure the Properties method specifies each non-key property only once.
I assume this is due to the default mapping of Identity already having UserName mapped. Can I override this or remove the default mapping somehow in order to achieve splitting the IdentityUser entity across multiple tables?
This is similar to this question but with using database first entity framework instead of code first:
How can I change the table names when using Visual Studio 2013 ASP.NET Identity?
In the code first approach you can override OnModelCreating and do something like this so that the user info is saved in MyUsers table instead of the default AspNetUsers:
modelBuilder.Entity<IdentityUser>().ToTable("MyUsers")
In the database first approach I have manually created the MyUsers table but because OnModelCreating does not get called I don't know how to configure the data to be saved into my new table?
You can follow the Code First approach an when overriding the OnModelCreating add the line:
System.Data.Entity.Database.SetInitializer<ApplicationDbContext>(null);
The line above will link the AspNetIdentity entities to your tables without re-creating the tables.
Code Example:
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<ApplicationUserRole>().ToTable("UserRoles");
modelBuilder.Entity<ApplicationUserLogin>().ToTable("UserLogins");
modelBuilder.Entity<ApplicationUserClaim>().ToTable("UserClaims");
modelBuilder.Entity<ApplicationRole>().ToTable("Roles");
System.Data.Entity.Database.SetInitializer<ApplicationDbContext>(null);
}
Using latest EF and EF SQL Compact (6.1.1) with SQL (4.0)....
Noticed via Linqpad that the table names generated through my initializer (DropCreateDatabaseAlways) are different than what I have specified in the Table attribute. When developing I am creating an embedded database for test purposes but other environment the database will be legacy which means the table names must match then.
If I have [Table("p_Brand_Visited")] on an entity the generated table name is P_Brand_Visiteds. The first letter is capitalized and the name is made plural. Not sure why the Table attribute is not respected. Maybe a SqlCe issue?
Tried via the OnModelCreating event to remove pluralizing:
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
No effect. Tried to set the table name:
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Entity<BrandVisited>().ToTable("p_Brand_Visited");
}
No effect. Any other suggestions? Ways to debug?
This was a problem with Linqpad and the plural options. Once these were disabled everything worked fine.
Using EF 5 RC what is the proper way to specify what schema tables are created under while using the Code First process?
I have tried:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Metric>().ToTable("Metrics", "Dashboard");
}
But the SQL script created doesn't recognize the schema and makes all the tables under the dbo schema.
TIA
J
If you right click on the EDMX designer surface and go to properties you can set the schema for that diagram. So if you want to put different entities/tables in different schemas you have to keep them on seperate design surfaces.
Currently I am deploying my application to a shared hosting environment and code-first with migrations has been working great except for one minor hiccup. Everytime I want to push the site I have to use the "Update-Database -script" option because I have to prepend every table name with [dbo] because by default the shared host creates a default schema name that is the same name as the database username.
If I log into my shared host and create a database, I then have to create a user. If I name that user admin, then the tables code-first creates while logged in as admin look something like this "[admin].[BlogPosts]". When the application runs all the tables are created but I get an EF exception because it says "[dbo].[BlogPosts]" is invalid. If I rename the table's schema name to "[dbo]" instead of "[admin]" that fixes it.
To get around this I have to generate a migrations script to be executed manually and add "[dbo]" in front of all the table names because the script only references the tables by their name, not by their schema and their name.
Is there an easy way to get around this? It would be so nice if all I had to do was publish the application and everything just worked. If it wasn't for the schema name discrepancy it would be a one click deploy and everything would be glorious.
For those using Entity Framework 6, just use the HasDefaultSchema method:
public class Contexto : DbContext
{
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("MyDefaultDbSchema");
}
}
You could use the ToTable method to specify the schema name. If you do not specify the schema name, EF will by convention use dbo.
public class MyContext
{
private string schemaName = "Foo";
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntity>().ToTable("MyTable", schemaName);
}
}
In EF Code first, by default, everything is set up based on user access with a managerial access "DBO-Schema" in the SQL Server. But if a specific user is defined to work with a database that is common in shared hosting, then there will no longer be Dbo management access. This time the names of our tables are dbo.tableName, for example, someUser.tableName, and inaccuracy of this point makes it impossible to run the program. To modify and explicitly assign a user connected to a database. If you use metadata, the following method should be used:
[Table("MyTableName", Schema="MySchemaName")]
public class MyClassName
{
//Other Lines...
}
Or (Whether or not Fluent API is customizable as follows:)
modelBuilder.Entity<Blog>().ToTable("MyTableName", schemaName:"MySchemaName");
Notice the following:
a good reference for study:
http://www.c-sharpcorner.com/article/fluent-api-in-code-first-approach/
For database-first implementations, it's easy. Open the edmx file, right click -> Properties and set the default database schema.
For code-first, this article seems most promising: https://web.archive.org/web/20150210181840/http://devproconnections.com/entity-framework/working-schema-names-entity-framework-code-first-design
I would like to add since this is for C#, I have written one below for VB
Public Class ClientDbContext
Inherits DbContext
Public Property Clients As DbSet(Of Client)
Protected Overrides Sub OnModelCreating(modelBuilder As DbModelBuilder)
modelBuilder.HasDefaultSchema("dbo")
End Sub
End Class