I am using ninject for my entities and have created a custom dbcontext, which holds my poco classes. This is CusDbContext . I then add *this to identity by adding it as a parameter in the base class constructor for ApplicationDbContext
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("CusDbContext", throwIfV1Schema: false)
{
}
So now in my webconfig the connection string is set to CusDbContext. This all works fine. On the initial create ( when i register a user and .net creates the db in background with all the user tables )
This database is local by the way (local)\v11.0
The tables are created and the user is added and all works fine. Then when i add migrations for code first it states
More than one context type was found in the assembly
Cool so i use my CusDbContext.
PM>Enable-Migrations -ContextTypeName Library.Data.Concrete.CusDbContext
PM>Add-Migration init
And i get the error
Library.Data.Concrete.IdentityUserLogin: : EntityType
'IdentityUserLogin' has no key defined. Define the key for this
EntityType.
That is a viewModel though (O.o)
Why is the migration trying to add a viewmodel as an entity? Is there any way to have one context type using identities default files? I still want to use ninject.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
This was needed on the ApplicationDbContext in order to build.
Related
I'm working on an ASP MVC project.
Here are the steps I followed :
I added entity framework in my project references
I connected to my SQL SERVER database and then copied the associated connection string in Web.config using this answer. The connection is successful
I created manually my own DbContex class. Below is its code :
public class MyConxtext : DbContext
{
public MyConxtext() : base("name = MyConnString"){}
public DbSet<user> user { get; set; }
}
Now user here not only is the name of my table user in SQL server but also is the name of my model user in my ASP MVC.
My problem is that :
- when I wanted to persist (several item in a session) via MyContext.SaveChanges(), it has created another table in my database named users ... Notice the plural here users... So instead of working on the table user, it created another table called users and persited data on that table.
My context also is not able to read data from the user table. BUT as I said it processes everything is the schema of the connection string
How can I solve that problem ?
Not only that it has also created another table in my schema called MigrationHistory which contain data about my project...
You can override OnModelCreating method in your DbContext and add the following line
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
This should remove pluralization for naming
Entity Framework by default pluralizes the table name when it generates it from the supplied entities.That means, if there is a class named Student as entity object and you declare a DbSet <Student> on your context (class inherited from DbContext), by default EF creates the table in a plural form of the entity name. This is a general concept as the table will contain several rows of that entity type, which refers it will be a collection of the entities, in our case it will make a table named Students.
If you want to remove this default convention (System.Data.Entity.ModelConfiguration.Conventions), you can override the method named
onModelCreating()
of DbContext class.
In your code you can do
public class MyConxtext : DbContext
{
public MyConxtext() : base("name = MyConnString"){}
public DbSet<user> user { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove < PluralizingTableNameConvention > ();
}
}
This will stop pluralizing the table's name in your database and it will use the user table of your database as you mentioned.
I'm using ASP.NET MVC5 with Identity 2 framework, Database first
I'm trying to custom AspNetRoles, by adding a column called MyCustomColumn
However, my app crashes because :
Invalid Column Name Discriminator
There is a lot of resources on SO and elsewhere on the web, but most of them are with CodeFirst approach and I can't use them in my app.
How to deal with it ?
Actually, none of this is necessary. Most likely you failed to update your context to inherit from IdentityDbContext<TUser, TRole, TKey, TUserLogin, TUserRole, TUserClaim>, rather than the default of IdentityDbContext<TUser>. Since you did not pass your custom role entity as the TRole type parameter, the context instead uses IdentityRole as the class type. It then creates a table for IdentityRole, sees that your custom role inherits from IdentityRole, and therefore adds the Discriminator column so that it can tell the different between an instance of IdentityRole and your custom role, in the database (single table inheritance is the default strategy EF employs).
This will technically work, but your custom role will never actually be utilized. Use the right generic abstract context class, and you'll be fine.
For what it's worth, you should do away with the EDMX stuff, as well. It's deprecated, buggy, and unnecessary. Despite the name, "Code First" can be used with an existing database or to create a new one.
DON'T
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
DO
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, CustomRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
Ok, as I spend some hours to find a solution, I post it here, if it could help someone else.
First, in AspNetRoles, create your custom column AND a column called Discriminator (which is a nvarchar(max) ). Update your .edmx
Then, we have to create a class which inherits from IdentityRole. We will use this class to access our custom column we just created :
In Models folder
public ApplicationRole()
: base() { }
public ApplicationRole(string name, long myCustomValue)
: base(name)
{
MyCustomValue = myCustomValue;
}
public virtual long MyCustomValue { get; set; }
Then, let's create a class which inherits from RoleManager<ApplicationRole>.
I placed it in IdentityConfig.cs, but maybe it's a best practice to place it elsewhere...
For information, I get inspired by this blog, Re-Implementing RoleStore and ApplicationRoleManager paragraph
public class ApplicationRoleManager : RoleManager<ApplicationRole>
{
public ApplicationRoleManager(
IRoleStore<ApplicationRole, string> roleStore)
: base(roleStore)
{
}
public static ApplicationRoleManager Create(
IdentityFactoryOptions<ApplicationRoleManager> options, IOwinContext context)
{
return new ApplicationRoleManager(
new RoleStore<ApplicationRole>(context.Get<ApplicationDbContext>()));
}
}
ApplicationRoleManager has a constructor which calls our previously created ApplicationRole class.
Now we have to register our ApplicationRoleManager at startup, so we have to add this line after the others CreatePerOwinContext
In App_Start\Startup.auth.cs, ConfigureAuth(IAppBuilder app) method
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
So now we can use our ApplicationRoleManager, correctly instanciated :
var rm = new ApplicationRoleManager(new RoleStore<ApplicationRole>(new ApplicationDbContext()));
And then use it as we want
var roleName = rm.FindByName("Admin");
string myCustomData = roleName.CustomData.ToString();
I want to make an MVC website with user logins/authentication etc.
I'm using EF CodeFirst to create my database.
If I create a new MVC project and select Authentication: Individual User Accounts, it will create a new project with an already existing IdentityDbContext etc.
Am I meant to continue using this along with my own DbContext? One context for my projects entities, and the other context for the Identity entities? Does this mean I'll have two separate databases, or can I give them both the same connection string?
I know this may be an open ended question, but are there any good resources/tutorials for AspNet Identity?
So far I've only been finding resources about AspNet Identity itself, and not how to integrate it with the rest of the project/database
You can specify the same connection string for both of your custom models context and identity context, all you have to do is to change the connection string in the constructor of the ApplicationDbContext class that resides in IdentityModels.cs file like so:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("YouCustomConnectionString", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
and the tables needed for identity will be created in the same database as your other entities, as for resource there is a good set of articles on identity here.
I am creating a new application using MVC 5 (Razor Views), Entity Framework 6 (Code First), ASP.Net Identity 2.0 and Web API. Trying to create a decent de-coupled architecture, I wanted to enable migrations in my data layer, but I have a misunderstanding of how migrations work. Here's my basic solution architecture:
MyApplication Solution
|-Domain Project
|-Entity1
|-Entity2
|-Entity3
|-Data Layer Project (References Domain Project)
|-DbContext (Inherits from IdentityDbContext)
|-Migrations Folder
|-Service Layer Project (Web API)
|-Business Layer Project
|-MVC Project
|-Views
As shown above, the Data Layer Project I have enabled migrations by executing the Enable-Migrations command in the Package Manager Console. The problem is, it only scripts the models related to Identity (AspNetUserRoles, AspNetUserLogins, etc.). How does a migration know to include an entity? I need it to script the models in my Domain project and not quite sure how to tell EF/Migrations to do so.
UPDATE:
Per a request, my simple (out-of-the-box via scaffolded by new project) DbContext class below:
public class MyDbContext : IdentityDbContext<ApplicationUser>
{
public MyDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static MyDbContext Create()
{
return new MyDbContext();
}
}
The problem is, it only scripts the models related to Identity
(AspNetUserRoles, AspNetUserLogins, etc.). How does a migration know
to include an entity?
The migration "knows" what to script as it scripts on a per context basis. Look at the Configuration.cs class in the Migrations folder and you will notice that it is a generic class with the DbContext type passed in as follows:
internal sealed class Configuration : DbMigrationsConfiguration<MyDbContext>
So it "knows" because you're explicitly telling it by passing in a MyDbContext generic type parameter.
So if you want to add your own entities classes for migration then you should have a DbSet for each of the entities in your DbContext. i.e.
public class MyDbContext : IdentityDbContext<ApplicationUser> {
public DbSet<Entity1> Entity1s {get;set;}
public MyDbContext()
: base("DefaultConnection", throwIfV1Schema: false){}
public static MyDbContext Create()
{
return new MyDbContext();
} }
If you don't want to reuse MyDbContext for your custom entites then you can create another context, and add your entity DbSets to that. But then you will have to explicitly enable and update the migrations as per How do I enable EF migrations for multiple contexts to separate databases?
I am building a single page application, so I used the visual studio default template.
When It was on development I had 2 databases Entityframework.mdf and Identity.mdf, because thats what the default configuration does, but now I need relation ship with the users and I can't reach them easly because they are in another database.
in an MVC template you can easly do it like this:
public class ApplicationUser: IdentityUser
{
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection")
{
}
public DbSet<CustomTableItem> CustomTable{ get; set; }
//You can add more tables
}
when you use the single page application it configures the user management in a way I don't understand.
UserManagerFactory = () => new UserManager<IdentityUser>(new UserStore<IdentityUser>());
then from this article
This code uses the default constructor for the UserStore class, which will create a new instance of an IdentityDbContext object since an object isn’t supplied. If you want to use your own IdentityDbContext derived class, like the MVC 5 project does, you can modify the above initialization code and pass in your own context.
it says I can modify it but it does not show how :(, and I have tried but I can’t make it work. This is what I am trying to do
UserManagerFactory = () => new UserManager<ApplicationUser>(new UserStore<ApplicationUser>());
what am I missig?
If you use default constructor (with not parameters) for UserStore class, this happens:
public UserStore()
{
this..ctor((DbContext) new IdentityDbContext());
this.DisposeContext = true;
}
Identity framework creates it's own database context for you with default connection string and no relation to your own models or DbContext.
What Scott says in his article is that UserStore has a constructor defined like this:
public UserStore(DbContext context)
{
base..ctor(context);
}
In other words you can supply your DbContext as a parameter into the constructor of UserStore:
UserManagerFactory = () => new UserManager<ApplicationUser>(
new UserStore<ApplicationUser>(new ApplicationDbContext()))
Where ApplicationDbContext is defined as you describe in the question.
You'll need to create a migration on ApplicationDbContext that will create Identity tables in Entityframework.mdf. Then you'll have to move data from Identity.mdf into your main database. Connect to both datbases and run something like this:
insert into EntityFramework.dbo.IdenetityUsers
select * from Identity.dbo.IdentityUsers
However, I've only done data migration from one DB to another one within single SQL Server instance, not between LocalDbs (I presume you used these). So this method might not work and you'll have to export data from Identity.mdf into csv files and import them into EntityFramework.mdf