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?
Related
I'm using code-first entity framework to create tables in a SQL database from objects. I'd like to have control over what types my variables are once they are in the SQL table.
For example, I have a table with a CountryName column. Currently, it has the data type nvarchar(MAX). I'd like for the data type to be nvarchar(40) to save memory.
I can do this manually in SSMS, but it'll take me a few hours to do this for all my tables. I'm looking for a way to do this in code.
Thanks in advance!
EDIT: I also want control whether or not my data type can accept NULL. So, I want to change all my data types (e.g., int, nvarchar, DateTime) to not accept NULL.
You could make use of DataAnnotations in general, in order to specify things like this. Specifically, in the case you mentioned you need to make use of the attribute called MaxLength:
[MaxLength(40)]
public string CountryName { get; set; }
You can use DataAnnotations to configure your model. To set the length to 40 you would apply the attribute MaxLength to a property.
[MaxLength(40)]
Or, as your question asks to do this in code you override the OnModelCreating in your DbContext and use the Fluent API to configure your model.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//Configure domain classes using modelBuilder here
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Student>()
.Property(p => p.CountryName)
.HasMaxLength(40);
}
Walk through all the pages in the following tutorial to learn all the different ways to configure properties in your mode.http://www.entityframeworktutorial.net/code-first/fluent-api-in-code-first.aspx
I would like Entity Framework v6 to not use quotes around identifiers when executing transactions against the database. Is it possible to configure the DbContext to do this without creating a configuration file for every entity?
For example:
Instead of
SELECT "ApplicationId"
FROM "dbo"."Applications";
I want
SELECT ApplicationId
FROM dbo.Applications;
Will Entity Framework be able to correctly map properties and entities to the database fields and tables correctly?
EDIT:
Rather than try to eliminate the quotation marks, I should have indicated that my goal is to interface with an Oracle DB. Oracle will require using quotation marks around identifiers that contain lowercase letters. So, I should probably change my request to indicate that I need all uppercase identifiers.
I came up with part of a solution in the OnModelCreating method of the DbContext, but it won't handle Foreign Key identifiers:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Properties()
.Configure(c => c.HasColumnName(c.ClrPropertyInfo.Name.ToUpperInvariant()));
modelBuilder.Types()
.Configure(c => c.ToTable(c.ClrType.Name.ToUpperInvariant()));
}
You can put the foreign key properties in your class, and then map their database column. Like this How to configure DbContext to work with Oracle ODP.Net and EF CodeFirst?
Or, if you don't want to put the foreign key property in the classes, you should use the fluent API to map the foreign key using uppercase letters. Like this example:
modelBuilder.Entity<Course>()
.HasRequired(c => c.Department)
.WithMany(t => t.Courses)
.Map(m => m.MapKey("CHANGEDDEPARTMENTID"));
Am I able to use Entity Framework models (Classes) as a classes for asp.net Identity
so the relations that I have in my database will be loaded when I retrieve the user and if I update any columns or add tables I only have to deal with Entity Framework model.
I did do my custom classes for users
public class MyUser : IdentityUser<long, MyLogin, MyUserRole, MyClaim>{ ... }
and connected it with the table
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<MyUser>().ToTable("Users");
.....
}
but I have more tables that are connected with 'Users' table that isn't with Identity model
for example:
I have a table called Person(Not really just an example)
and each person may have many users and each user may have many
persons
So We have another table called 'PersonsUsers'
So the user have a list
I don't want to call the database twice to retrieve a single user data, and mapping the table from code will make my code static and depends on me updating the source code.
so Is it possible to use the classes that EF generated for the tables?
Do you have any other solution?
Yes, this is possible. Your MyUser class could have a property with the list of Person. then in your modelBuilder, you set up the mappings. Something like this:
modelBuilder.Entity<MyUser>().HasMany(m => m.Person)
.WithMany(p => p.MyUser)
.Map(m => {
m.ToTable("PersonUsers");
m.MapLeftKey("MyUserID");
m.MapRightKey("PersonID");
I believe this will accomplish what you're looking for.
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);
}
I'm using EF 4.3 code-first with an Oracle database. One weird thing about the database is that it automatically makes table and column names ALL CAPS. My domain properties are in PascalCase. Unfortunately, EF doesn't know to capitalize column names, so my queries don't work. I have hundreds of properties on several classes that should map to oracle columns. I would really rather not manually code all those mappings. Is there a way to use a convention to capitalize column names?
SUMMARY:
I need for Entity Framework to use ALL CAPS for all column names. How can I do that?
Haven't tried this, but what about something like this:
public class SomeEntities : DbContext
{
public DbSet<Entity> Entities { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Configure Code First to ignore ColumnTypeCasing convention
modelBuilder.Conventions.Remove<ColumnTypeCasingConvention>();
}
}