I'm learning ASP.NET Core and I'm having some problems with the following scenario:
I created an extension class for IdentityUser provided by Microsoft.AspNetCore.Identity, the extension class add some extra field to the default database AspNetUsers:
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime BirthDate { get; set; }
public string LockoutMessage { get; set; }
public string SessionId { get; set; }
}
I was able to update the table structure executing the following commands:
add-migration <migration name> -context <app context>
update-database
Problem
Suppose now I used the software Microsoft SQL Server Management Studio for create another table called UserDetails which have as FK the id of the AspNetUsers table.
I want generate the class inside the Models folder with all the properties from my application, so I don't need to write manually the property of the table of the new table, how can I do that?
I tried: update-database but not seems to work.
The only way to bring in stuff from a database is with Scaffold-DbContext. However, that's an all or nothing affair. It's going to create entity classes for every table in the database (regardless of whether they already exist) and a DbContext to boot.
Either you're using code first and you create your entities and generate migrations that you run against the database OR you make changes to the database and then use the Scaffold-DbContext command to generate the context and all the associated entities. You cannot mix and match.
Long and short, you need to pick a strategy and stick with it. If you're more comfortable with the database then do everything there and scaffold the code from that. Otherwise, if you want to use code first, then make a commitment to that and never manually touch your database.
Related
My app performs Authentication with Asp.NET Identity.
The users logging in are stored in dbo.ASPNetUsers
A while ago, I used migrations to add another table called "Customer", but now the table is populated.
How can I add a controller to perform CRUD operations ONLY on existing "Customer"(the other tables have controllers) without dropping the table and risking erasing any of its content or any other content in the existing tables in the db.
What I tried so far:
Create class in Models folder called "Customer" to resemble the table columns
public class Customer
{
[Key]
public string ID {get;set;}
public string FirstName {get;set;}
public string LastName {get;set;}
}
Add DbSetCustomers
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
// : base("DefaultConnection", throwIfV1Schema: false)
: base("MS_TableConnectionString", throwIfV1Schema: false)
{
}
public DbSet<Customer> Customers { get; set; }
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
}
Add new Controller of type Web API 2 Controller with actions using Entity Framework using model class Customer, with data context class as the default ApplicationDBContext (default option when creating controller, im assuming it uses my app connection string for the azure table).
When using the GET customers in POST, I get an error saying the database has changed since last migration, I Imagine this is because adding the DbSet Customers but I do not want to update migration because in the migration code, there is Drop Table command.
Is this right method?
Should I just change the migration script not to drop the table?
Please advise.
"Database has changed since last migration" , it s a way of EF telling that your migration history doesn't match with the tables.
EF's default database generation workflow creates a full script that will recreate your database every time you select Generate Database from Model, so if you execute it in your DB you will lose all your data. However, if you just create a new Entity and did not change the existing ones, then you can still generate database from your Model but then take that script and only run the part that creates the new table for your new entity.
You can take a look at the below link for further reference:
https://www.apress.com/gp/blog/all-blog-posts/secular-trends-for-the-cloud/12097630
https://social.msdn.microsoft.com/Forums/en-US/ed3ccb7e-5e89-4fd4-ae92-d641a5c5bd9a/entity-framework-model-first-make-changes-to-the-database-without-dropping-tables?forum=adodotnetentityframework
https://www.pauric.blog/Database-Updates-and-Migrations-with-Entity-Framework/
Hope it helps.
I am using code first entity framework approach. I have changed the name Plane_EcoClass to Plane_Class property to the table in the database. It is showing with old property name in the db .How can I update the new property name?. Please let me know how to resolve this error.
public class Plane
{
[Key]
public int Plane_id { get; set; }
public string Plane_Name { get; set; }
public string Plane_No { get; set; }
public string Plane_Class { get; set; }
public virtual List<User>Users { get; set; }
}
you need to add a migration and update the database for the change to affect the database. In the package manager console, type something like:
add-migration YourMigrationName
to create the migration. Review the migration code. Be aware that Entity Framework may try to drop the previously named column and add a column for the new name. This can potentially cause data loss. If this is the case and not desired, then you can manually change the code to use the RenameColumn method.
After adding the migration, you can apply it to the database by going back to the package manager console and typing:
update-database
and then hitting enter. At this point, the package manager console will give you some output regarding running migrations and your seed method and then the database should reflect the updated column name
I have seen several tutorials and examples about starting with a new database, and about adding columns and fields to models/existing tables. I need to add 2 new tables to a production database without messing with the existing tables.
I tried creating 2 new models and then using add-migration like I did with fields for existing models but this did not work, it created an empty migration with an empty Up and empty Down field.
I'm iffy to do anything because I am going to have to do this to a production DB after I get it working on test DB.
Bascially:
public class ChatModel {
public int Id { get; set; }
public string CaseNumber { get; set; }
public string AgentName { get; set; }
public string CustomerEmail { get; set; }
public DateTime Time { get; set; }
public string Transcript { get; set; }
public virtual SurveyModel Survey { get; set; }
}
and
public class SurveyModel {
[ForeignKey("ChatModel")]
public int ChatId { get; set; }
public int Id { get; set; }
public string Question1 { get; set; }
public string Question2 { get; set; }
...
public virtual ChatModel Survey { get; set; }
}
First Point : Why Up and down functions are empty?
Check your Migrations directory inside your project. It contains all the classes for migration which get created in Timestamp_MigrationName format. You might want to check few most recently created files in that directory to see if your recent model related changes (two new tables) are already present in any one of them. Possibly because of execution of the Add-Migration command more than once your new migration files which are getting created are coming empty as EF is not detecting any new model changes since you ran Update-Database command last time.
Second Point : How to update the production database with latest Model changes which has two new tables
Updating the production database is a crucial thing. I don't think you are planning to update your production database directly from your development environment by running Add-Migration and Update-Database command. It is highly risky and never recommended. Using the pair of "Add-Migration" and "Update-Database" commands is the right way if you intend to update your development/local database. For updating your production database here are the set of commands which you should be firing:
Remove the _MigrationName.cs file from Migration folders under your project which contains the changes related to your two new tables. This step is required only because you are getting empty Up and Down functions whenever you are running Add-Migration command. Otherwise this step would not have been required if everything was smooth.
Run the command Add-Migration AddNewModels on package manager console.
Run the command Update-Database -Script on package manager console. This step creates a .sql extension file which will contain all the t-sql queries (DDL statements) required to make all the new schema changes. Visual Studio opens the newly created *.sql file automatically in front of you for a quick review and saving at a path of your choice.
Run the command Update-Database to commit the changes to your local/development database. This step is required else you will not be able to start new migrations if you desire.
Now hand-over the scripts file which got created in step # 3 above to your production DBA and you are good to go. You production database upgrade will happen seamlessly without any errors and your application will be compatible with the changes.
I want to add 2 Extra fields in UserProfile Asp.Net Simple membership, But unable to add and not find any help from internet. Please give me some solutions.
Thanks in advance
To add fields to UserProfile in SimpleMembership (I will assume you want to use migrations and EF):
Ensure you have enabled migrations (use the Enable-Migration in the package manager console)
Edit the UserProfile class (assuming you are using, for example, the Visual Studio 2012 -> New Project -> ASP.NET MVC 4 Web Application -> Internet Application template, this will be created for you) to add your new properties (example below)
Add a migration which will update your database using the Add-Migration command.
Optionally edit the generated migration to handle default values and non-nullable fields.
Run that migration against your development database using the Update-Database command.
I have provided an overview about how SimpleMembership works, with UserProfile in this answer. Note that UserProfile can be moved from the UsersContext to the same DbContext as all your other classes, it does not have to be in a separate context.
SimpleMembership is designed to play well with code-first EF development, so that is the process I have outlined above. An example updated UserProfile class with a Forename, Surname and a LoginCount field would look like:
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
[MaxLength(40)]
[Required]
public string Forename { get; set; }
[MaxLength(40)]
[Required]
public string Surname { get; set; }
[Required]
public int LoginCount { get; set; }
}
References:
ASP.NET MVC 4 Entity Framework Scaffolding and Migrations - task 3 shows how to enable migrations
MSDN: Code First Migrations - everything you need to know about migrations
StackOverflow: How do I use my own database with SimpleMembership and WebSecurity? What is MVC4 security all about?
I've made use of the administration tool to create users and roles.
What I'm trying to do is create another table..
public class TaskModel
{
public int Id { get; set; }
public string Time { get; set; }
public string Description{ get; set; }
public class TaskDBContext : DbContext
{
public DbSet<TaskModel> Tasks { get; set; }
}
}
..and create a foreign key to the UserId (Users table) and to the RoleId (Roles table) - (which are both automatically created by the admin tool). The site administration tool does not create models for the tables so I don't know how to point to it and create the foreign keys. (I believe this post described creating FK's between two different classfiles but I cannot apply it: How Should I Declare Foreign Key Relationships Using Code First Entity Framework (4.1) in MVC3?).
Also another question; I know how to display TaskModel records in a view, but how do I filter those results with the foreignkeys in it? What I mean is filter by UserId (logged in user) and/or RoleId? (this question is less important then question above).
You could write a custom membership provider that the website administration tool will use. In your custom membership provider, you will create the records in your extra table, and insert them into the users table when a user is created. If you need any special user interface for this, then you'll have to write your own user administration tool.
http://www.codeproject.com/Articles/165159/Custom-Membership-Providers