I installed nuget packages for asp.net identity and followed this MS tutorial which, by creating a new user, creates all of the tables e.g. AspNetRoles, AspNetUsers in my database.
The problem is, I'm trying to use CodeFirst migrations for DB source control and my Visual Studio side has none of the models for these tables. I don't want the "Create user" method to automatically create the tables, I need to get my models in Visual Studio and then push it using a migration.
Currently I have all the [AspNet] tables in my database and no reflection of this in my migrations. I can delete the tables but need to know how to populate the code first!
I'll also probably need to customise the models later, but that's another issue.
You can extent your asp.net identity as bellow
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public DbSet<Employee> Employees { get; set; }
public DbSet<Attendance> Attendances { get; set; }
public DbSet<PunchRecord> PunchRecords { get; set; }
}
Took me two hours to find I simply needed to add a model that inherits IdentityUser and then add a migration. I've called the model "ApplicationUser" - based on a tutorial I found on how to extend AspNetRoles and an answer somewhere in stackoverflow, it seems this name is possibly automatic or scaffolded somewhere... but I just chucked it manually in my Models folder:
public class ApplicationUser : IdentityUser
{
}
Also, I had to tinker with my application's context to inherit from IdentityDbContext - this way I don't need two separate connection strings and my app context is now all inclusive.
Related
I am new to fairly new to programming and started a new project using asp.net core and MVC.
Since i wanted to see what was going on behind the scenes, i implemented authentication and authorisation manually using IdentityUser and IdentityDbContxt.
During the initial migration, a bunch of tables were created that allows the users to register and then login in. I have implemented all of that.
Now I want to create a new table within the same database that will let the users submit their names and address. I believe i can just create a new table using sqlite GUI and work with that, but how do I create a UserProfileModel.cs file and have that schema show up on the database?
My apologies if my question is not very clear. Also , I am working with microsoft stack on a mac :).
Thanks.
First of all, you can always extend the IdientityUser, add migration, update the database and names and addresses will be added to the table.
public class UserProfileModel:IdentityUser
If you want to have more models with tables, you have to make a class that extends the IdentityDbContext, pass the db options to the constructor and add your DbDets, wich will be use for creating the tables.
public class AppDbContext : IdentityDbContext<User>
{
public DbSet<UserProfileModel> Residences { get; set; }
public AppDbContext (DbContextOptions<AppDbContext> options) : base(options)
{
}
Then, where you configure the services you have to add the database,
services.AddDbContext<AppDbContext>(options => options.UseSqlite(configuration.GetConnectionString("Your Connection String")));
I assume you have already made that, maybe with IdentityDbContext, but you can add your custom DbContext.
Now you can inject your AppDbContext wherever you want to use it. Probably to a service or a repository.
There are similar questions with this issue, but not for EF Core. Not a duplicate of Entity Framework Core Using multiple DbContexts . That one is related to not being able to access the database at all from the second context, and the two contexts use different databases. This question is about a single database and the issue is related to migrations
I have two EF core db contexts using the same SQL Server database.
In the first context I have many entities, one of them is User.
In the second one there is a single entity called UserExt which has a navigational property to User
public class UserExt
{
[Key]
public long UserID { get; set; }
public virtual User User { get; set; }
[Required]
public string Address { get; set; }
}
The issue is that when creating the migration for UserExt using 'add-migration', all entities from the first context are also included.
Tried providing the context, but same result
add-migration --context SecondContext
With EF 6 it was possible to solve this using ContextKey (https://msdn.microsoft.com/en-us/library/system.data.entity.migrations.dbmigrationsconfiguration.contextkey(v=vs.113).aspx) but has not been ported to EF Core
Is there a way to make this work so that the migrations in the second context would contain only its entities ?
Solved using database context inheritance. This way I can have separate migrations.
public class SecondDbContext : FirstDbContext
{
public virtual DbSet<UserExt> ExtendedUsers { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("connectionString", options =>
options
.MigrationsAssembly("SecondDbContextAssemblyName")
.MigrationsHistoryTable("__SecondEFMigrationsHistory") // separate table to store migration history to avoid conflicts
);
}
}
Because SecondDbContext is inherited from FirstDbContext, every entity change made in the base context will be inherited. Which means that when a new migration is added to the second context, it will try to apply the changes again from the first context again. Workaround is to:
Add a new migration (for example Add-Migration Inherit_FirstDbContext)
Delete everything from the migration's Up and Down methods
Apply the empty migration in the database. (Update-Database)
This ensures that the Entity Framework snapshot will contain the changes, without actually having to re-apply them in the database.
I am building an app using ASP.Net MVC 5 framework with a database code approach.
I need to add custom fields to my Users Table. What is the best way to add custom attributes and access them later?
Here is what I have done so far
Logged into SQL Server and added the column to the AspNetUsers
table.
I created a new class which ApplicationUser like myUser class below.
public class User : ApplicationUser
{
public int UserId { get; set; }
public int CampId { get; set; }
}
Additionally, I tried adding my custom attributes to the ApplicationUser directly like the insstruction found on the answer in another question, but I get the following error
The model backing the 'ApplicationDbContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).
What is the best way to add column to my AspNetUsers table?
Also, How can I access these field from the controller using the Authorized user?
You have to use code-first migrations.
In VS go to Package Manager Console and type:
enable-migrations
then you can add properties to your ApplicationUser class like Birthday or whatever.
Then go back to Package Manager Console and run:
Add-Migration aNameForYourMigration
So for example if you've added a Birthday property you would perhaps name it BirthdaypropertyAddedMigration or whatever makes sense to you.
Then run:
Update-Database
now all your changes to the ApplicationUser class will be persisted to the database.
But if you do the database approach, you have to add the new fields to the users table and then call update model, to regenerate the code.
Let's say I have a simple site with one context
public class DataContext : DbContext
{
public DbSet<Stuff> Stuff { get; set; }
}
and one model
public class Stuff
{
public int ID {get;set; }
public string Name {get;set;}
}
And I'm using code-first EF model, and I hit update-database and it creates my tables and then I publish my site. Everything is great. However, then I decide I want to add a property to my model
public class Stuff
{
public int ID {get;set; }
public string Name {get;set;}
public int StuffType {get;set;}
}
And now I hit update-database and it updates the database with the new property, but the published site is now broken because its model is out of date with the database model.
Other than frantically trying to republish the site before anyone notices, is there any other way work with code-first migrations without breaking a published site?
Do I need to have two databases? If so, how do I then maintain the models between the two? This is further compounded by the fact that I usually have (at least) two git branches, and the published site is running the code from the master branch and I'm working on a develop branch - which is where I'd be modifying my models.
What is the usual workflow for avoiding these sorts of problems?
Try disabling the database initializer for your DataContext.
See this answer Entity Framework 6.1.1 disable model compatibility checking
I am following along Pro ASP.NET MVC 4 by Adam Freeman on VS 2010 (I downloaded the MVC 4 template online). I have worked with the .edmx file before, but in Chapter 7 he does not do this. I setup a basic connection string with SQL Server in my web.config file within my WebUI project where my controllers and views are located. Also, I listed my Domain classes within my Domain project below. The problem comes when I run the application. The application is not recognizing my table in my database (dbo.Request) and instead is creating a table based on my class name in the Entities namespace (so it creates a CustRequest table) and it also creates a _Migration_History table. To prevent this I add the Data Annotation above my class [Table("MyTableName")]. I could not figure out why I had to add this Data Annotation. Also, EF made me add a [Key] above my primary key, which i can understand because i do not have an ID property, but in the book he did not do this. I was wondering if I was missing something obvious as I am pretty new to MVC. Any help would be appreciated. I am working with EF 6. Thank you.
namespace Requestor.Domain.Entities
{
[Table("Request")]
public class CustRequest
{
[Key]
public int RequestId { get; set; }
public string RequestByUserCd { get; set; }
public DateTime RequestDateTime { get; set; }
public DateTime DueDate { get; set; }
}
}
namespace Requestor.Domain.Abstract
{
public interface ICustRequestRepository
{
IQueryable<CustRequest> Request { get; }
}
}
namespace ITRequestHub.Domain.Concrete
{
public class EFDbContext : DbContext
{
public DbSet<CustRequest> Request { get; set; }
}
}
namespace ITRequestHub.Domain.Concrete
{
public class EFCustRequestRepository : ICustRequestRepository
{
private EFDbContext context = new EFDbContext(); //retrieves the data
public IQueryable<CustRequest> Request
{
get { return context.Request; }
}
}
}
Consider trying again with EF5 if you can, I experienced similar issues when trying to make EF6 work with MVC4 (I couldn' make scaffolding work either).
Or go all the way up to the latest versions for everything and try MVC5 with EF6 (this seems to work fine)
You've run into the wonderful and sometimes frustrating part of EF, its conventions. Wonderful when you're aware of the conventions as they simplify life, but frustrating when you feel that the framework is performing tasks without your explicit permission.
Firstly, additional information on EF6 conventions can be found here: http://msdn.microsoft.com/en-gb/data/jj679962.aspx
On your first point, as far as I'm aware, EF takes the name of your entity as the name of the table it will create in your DB. As you've discovered, you do have control over this via the "Table" attribute, but you can also control it's desire to want to pluralize your entity names when creating tables by means convention removal within your DbContext
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>()
On your second point, I cannot imagine that you would require a "Key" attribute attached to your "RequestId" field. The convention here is that if the field name contains a suffix of ID (case-insensitive), then EF will automatically include it as a primary key and if the type of the field is either an Int or a Guid it will be automatically set as an auto-seed identity column.