Web API Add controller with CRUD operations for existing Azure table in Existing Azure db - asp.net

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.

Related

EF not creating identity table when trying to create new database

I have 2 model classes:
Customer.cs with name and Id
Movies.cs with name and Id
I tried to run enable-migrations, but I got this error:
No context type was found in the assembly WebApplication2'.
Then I saw some answers on websites and people told to make a DBContext class. I do not have any DBContext class as I just made a new MVC project.
So, I tried to make a DbContext class of my own as follows:
{
public class MyDBContext:DbContext
{
public void MyDbContext()
{
}
}
}
Then I was able to run enable-migrtaions command and Migration folder was created with configuration.cs as follows:
internal sealed class Configuration : DbMigrationsConfiguration<WebApplication2.Models.MyDBContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(WebApplication2.Models.MyDBContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data.
}
}
}
Now when I run the add-migration Initialmodel the Up() and Down() methods are empty and there are no Identity tables.
Please help !
First off I suggest you refer to creating a new MVC project using Entity Framework. There are a lot of tutorials but here's the Microsoft one which is accurate and pretty complete:
Get Started with Entity Framework 6 Code First using MVC 5
It also includes a section on Migrations, however you don't need Migrations until you have a database and a model that's changing.
I would suggest backing out your Migrations until we're ready for them. Rick Strahl has a good article on how to back them out and get back to a clean state:
Resetting Entity Framework Migrations to a clean State
Finally, your DbContext class has to have a DbSet. A DbSet class is an entity set that can be used for create, read, update, and delete operations. With your DbContext class as it is, Entity Framework has no idea what to do or map.
Change your DbContext class to something like this:
{
public class MyDBContext:DbContext
{
public void MyDbContext()
{
}
public virtual DbSet<Movie> Movies {get; set;}
public virtual DbSet<Customer> Customers {get; set;}
}
This will allow you (say in a Controller) to do something like this to add a new Customer to the database:
var customer = new Customer { name = "John Smith" };
using(var context = new MyDbContext())
{
context.Customers.Add(customer); // adds the customer to the DbSet in memory
context.SaveChanges(); // commits the changes to the database
}
NOTE: I don't recommend creating a DbContext this way in a controller, in the first link on using EF6 with MVC 5 there are better ways.
Hope that helps.

How to update / generate database table model?

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.

Creating new project with asp.net Identity and Database First [duplicate]

I need to integrate Asp.Net latest MVC version with an existing database which has an additional column String Address to table dbo.AspNetUsers
I need to create an instance ApplicationUser which has property Address.
Any idea how to do it?
A possible solution which works for me, basically I am able to integrate Asp.Net Identity User Profiles with an existing Database.
Getting the Asp.Identity Tables:
Create an MVC Project with Authentication Individual User Account
Open the DB listed under the DefaultConnection in Web.config. It will be called (aspnet-[timestamp] or something like that.)
Script the database tables using SQL Server Management Studio (attach database for mdc).
Alternatively use something like http://identity.codeplex.com/
Integrating with your existing db:
Insert the scripted tables into existing database in SQL Server Management Studio.
Customize and add relationships to ApplicationUser (if necessary).
Create new Web Project > MVC > DB First Project > Import DB with EF ... .
In IdentityModels.cs change the ApplicationDbContext :base("DefaltConnection") to use your project's DbContext.
Now you have the Asp.Identity Tables in your db with ER model in your application.
Asp.Identity Profile Adding new properties:
Enable Entity Framework Code First Database Migrations, just in VS go under Tools ‘Package Manager Console’,
Execute the command “Enable-Migrations”; Once we enabled the database migrations, we can go ahead and add new properties for our UserProfile
To Add new properties modify IdentityModels.cs file, example:
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string EmailID { get; set; }
}
Add New Migration
Once we added the properties, bring the Package Manager Console and execute the following command.
Add-Migration “YouMigrationName”
This command will generate a database script file, now execute following command to run this script file against the database.
Update-Database
Now, all the new properties will turn into table fields in the same database table.
I hope it can help others, if you have a better idea please let me know.
Take a look at these projects on GitHub:
https://github.com/kriasoft/AspNet.Identity - Identity Database Project + VS Template
https://github.com/kriasoft/AspNet-Server-Template - Sample / reference project
Which includes:
SQL Database Project Template for ASP.NET Identity 2.0
Entity Framework Database-First Provider(s)
Source Code and Samples
I had recently the same problem. I had an apllication created with DBFirst aproach and I needed to add Identity. This is what I did.
Install the next packages:
1. Microsoft.EntityFrameworkCore
2. Microsoft.EntityFrameworkCore.Design
3. Microsoft.EntityFrameworkCore.SqlServer
4. Microsoft.AspNetCore.Identity
5. Microsoft.AspNetCore.Identity.EntityFrameworkCore
6. Microsoft.AspNetCore.Aututhentication.JwtBearer
Do DbContext inherit from IdentityDbContext, like this:
public partial class BookStoresDBContext : IdentityDbContext
OnModelCreating I called the base constructor in order to avoid an error like "'IdentityUserLogin' requires a primary key to be defined"
protected override void OnModelCreating(ModelBuilder modelBuilder) {
base.OnModelCreating(modelBuilder);
}
As far as it was a created project the StringConnection was already there, if not add it.
On the Startup.cs configure Identity service on ConfigureServices
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<BookStoresDBContext>(options => options.UseSqlServer(Configuration.GetConnectionString("BookStoreDB")));
services.AddIdentity<IdentityUser, IdentityRole>(options =>
{
options.Password.RequireDigit = true;
options.Password.RequiredLength = 5;
}).AddEntityFrameworkStores<BookStoresDBContext>()
.AddDefaultTokenProviders();
}
You can configure the Authetication service too
services.AddAuthentication(auth =>
{
auth.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
auth.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options => {
options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
RequireExpirationTime = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("Your key to encrypt"))
};
});
Then run the migration from the Package Manager Console
Add-Migration InitDb
On the migration file, remove all the migrationBuilder.CreateTable for the tables you already have in your Database
Update the Database from the Package Manager Console
Update-Database
Then you will see the Identity Tables on your db
I hope it result usefull 😁
Don't forget to add migrations and update the database. Otherwise it throws a dependecy injection exceptions for the identity.
public class MyUser : IdentityUser
{
public virtual MyUserInfo MyUserInfo { get; set; }
}
public class MyUserInfo{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class MyDbContext : IdentityDbContext<MyUserInfo> //Edited to MyUserInfo
{
public MyDbContext()
: base("DefaultConnection")
{
}
public System.Data.Entity.DbSet<MyUserInfo> MyUserInfo { get; set; }
}
Getting Profile information
When the User Logs in, you can display the profile information by doing the following
Get the current logged in UserId, so you can look the user up in ASP.NET Identity system
var currentUserId = User.Identity.GetUserId();
Instantiate the UserManager in ASP.Identity system so you can look up the user in the system
var manager = new UserManager<MyUser>(new UserStore<MyUser>(new MyDbContext()));
Get the User object
var currentUser = manager.FindById(User.Identity.GetUserId());
Get the profile information about the user
currentUser.MyUserInfo.FirstName

asp net mvc adding a new property to model

I'm new in asp.net mvc. I'm trying to learn entity framework after the database has been created by the first code starting, i m adding a new porperty to model, but controller and view are not updating themselves automatically.
public class test
{
public int ID { get; set; }
public string Name { get; set; }
public string Surname{ get; set; }
}
in this simple I add Surname property after database created. I update database, but view and controller side do not update themselves automatically.
So should I make all changes manually like changing controller "create edit delete" post action.
thanks for answer
You most likely used scaffolding to create them first. If you want to have the properties listed in the view you need to recreate the scaffolding so it knows that property exists. To do that right click on the controller folder add new scaffolded item, like you did before.
You need to update the binding white list so your new property will be included, For this use Ctrl+Shift+B [For Visual Stdio]
after that do the Migration and update the database.

Including Identity User with Entity Framework doesn't work

I am having trouble including my Identity User in query results. Other entities are included just fine, no matter how many levels deep.
Here's the model I'm using.
Building * --- 1 City
* *
| /
| /
1 1
ApplicationUser
And the context:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public DbSet<City> Cities { get; set; }
public DbSet<Building> Buildings { get; set; }
}
Both Building and City have these properties:
public Guid ApplicationUserId { get; set; }
public virtual ApplicationUser ApplicationUser { get; set; }
The query I'm using to retrieve data:
var building = context.Buildings
.Include(c => c.ApplicationUser)
.Include(c => c.City)
.Include(c => c.City.ApplicationUser)
.First();
In the result City is populated just fine, however ApplicationUser is not.
Could this be a naming issue? I've already tried UserId / User and AspNetUserId / AspNetUser as property names without succes.
I'm using Migrations to create the database. The table name that gets created for users is AspNetUsers.
I'm using entity framework 7 beta 7, not sure if this applies to other versions as well.
These are the files generated by EF Migrations.
ApplicationDbContextModelSnapshot.cs
20150929181902_Init.cs
20150929181902_Init.Designer.cs
(I noticed I forgot to include the Building > City relation when generating files for upload, but that shouldn't matter for the example)
I've finally figured it out.
ApplicationUser inherits from IdentityUser which inherits from IdentityUser<string>. The generic type is used as the primary key, so a string!
I changed my Guid foreign key properties to strings and now everything is working.
Just to help anyone who also have a similar issue. I was facing same thing, same scenario: My custom identity user has some related entities and using .Include was not working. None of them would come back. But they used to.
Turns out I had created a custom ApplicationUserStore to automatically include the entities I would normally always need when retrieving a User but I had only overridden FindByIdAsync method. When I tried to use FindByNameAsync no entity would come back, obviously. Just had to override this and the other Find methods.

Resources