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.
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.
As you know Boilerplate don't give the entity classes to add columns and I want to add column in table named ( AbpUser). I tried to make a class in Migrations like below
public partial class AddRatingMig : DbMigration
{
public override void Up()
{
AddColumn("dbo.AbpUsers", "UserType", c => c.String());
}
public override void Down()
{
DropColumn("dbo.AbpUsers", "UserType");
}
}
Then in Pm console run command Update-Database
. But not successful. As you know Boilerplate don't give the entity classes to edit columns. Please Help Thanks in advance
The answer to this question is to Extend the AbpUser like this
public class User : AbpUser<User>
{
public string SpecialTitle { get; set; }
}
and add-migration UpdatedUserWithSpecialTitle
then update-database
Here is the correct way
public partial class AddRatingMig : DbMigration
{
public override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "UserType",
table:"AbpUsers",
nullable:true
);
}
public override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name:"UserType",
table:"dbo.AbpUsers"
);
}
}
Hence update Database using code as: update-database
NOTE:
Make sure that you have properly added migrations as:
add-migration migration_name
I had the same problem in abp.io framework, adding new property, "PICUstomerId" to AbpUser Entity and migrate it to database.
Here is the comments by abp.io:
Add your own properties here. Example:
public string MyProperty { get; set; }
If you add a property and using the EF Core, remember these;
Update PasargadInsuranceDbContext.OnModelCreating to configure the mapping for your new property
Update PasargadInsuranceEfCoreEntityExtensionMappings to extend the IdentityUser entity and add your new property to the migration.
Use the Add-Migration to add a new database migration.
Run the .DbMigrator project (or use the Update-Database command) to apply schema change to the database.
and finally add-migration to your solution and then update-database
1. Add your own properties here
2. Update PasargadInsuranceDbContext.OnModelCreating
3. Update PasargadInsuranceEfCoreEntityExtensionMappings to extend theIdentityUser entity
4. And finally after update-databse, I saw my new property in database
I'm working on an Asp.Net Mvc application then i want to seed my database using custom Database initializer class that I created.
so here is my DbContext :
public class ApplicationDbContext : IdentityDbContext<ApplicationUser> {
public ApplicationDbContext()
: base("defaultConnection", throwIfV1Schema: false) {
}
static ApplicationDbContext() {
Database.SetInitializer(new ApplicationDbInitializer());
}
and here is my ApplicationDbInitializer class :
public class ApplicationDbInitializer : DropCreateDatabaseIfModelChanges<ApplicationDbContext> {
protected override void Seed(ApplicationDbContext context) {
InitializeIdentityForEF(context);
base.Seed(context);
}
public static void InitializeIdentityForEF(ApplicationDbContext db) {
// Create Role Admin if it does not exist
// Add user admin to Role Admin if not already added
// And some more initializing stuff
}
}
Note: I'm using Migrations too.
so when i try to update and seed my database using command Update-Database (even if I delete database manually) , the database is being created but it does not seed it.
if I am doing anything wrong or it has other ways I'll be thankful to get your assistance.
This sounds like the same issue as in this question.
So, the seed code will only run when you create an instance of your ApplicationDbContext.
Add some code like this to your application startup:
var ctx = new ApplicationDbContext();
ctx.Database.Initialize(true);
Then your database will be seeded the next time your app starts.
Alternatively, if you wanted to use the Update-Database command to seed your database, that uses a different Seed method. You can see an example here.
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
I am new to ASP.Net, if my question sounds very basic, please be polite.
I have created a ASP.Net MVC4 project. A page in the application will display names of the files in tabular form.
The names of the files are obtained by finding files in a particular folder on the server. So there is no need for me to have a database for model.
When user opens the page, the server side code will list all the files in the directory and should return a list of Strings.
I am following ASP.Net MVC tutorial here and it appears I have to have a DBContext class and also a database. In my case that's not needed
So that question is can I add my model without having to add code like below and still be able to use the feature of model ? any simple example would be great.
public class MovieDBContext : DbContext
{
public DbSet<Movie> Movies { get; set; }
}
Any class can serve as a model in this case. For example, if you just want to have a Movie model, you can have something as simple as this:
public class Movie
{
public string Title { get; set; }
}
A view can bind to that model, to an enumeration of that model, etc.
For fetching your data from the file system, one approach could be a simple factory method on that model. Maybe something like this:
public class Movie
{
public string Title { get; set; }
public static IEnumerable<Movie> GetMovies()
{
// get the list of movies from the file system, for example as a list of strings
var movies = SomeFileSystemInteraction();
return movies.Select(m => new Movie { Title = m });
}
}
Then in your controller you can get the list of movies to bind to the view:
public ActionResult Index()
{
return View(Movie.GetMovies());
}
There's no need for a database, it's just used in tutorials because it's the most common case. But you can bind your views to any object you'd like.
You do not need that MovieDBContext class if you are not dealing with database. But having a model is a good idea to represent your entity(in this case the Folder). It is just a POCO class.
public class Folder
{
public string Name { set;get;}
public int NumberOfchilds { set;get;}
//Other properties as needed.
}
Now you can use the Model class to pass data between differnt places. For example. You can move the code which reads the data from file system to a Service class method and the method can return a list of this class/A single instance of this class as needed. Your controller action method can call the service method.
public class FolderService
{
public Folder GetRecentlyCreatedFolder()
{
var folder=new Folder();
//Set the properties of this object
// folder.Name="MySecret";
return folder;
}
}
and in your Action method
public ActionResult Items()
{
var srv=new FolderService();
var recentFolder=srv.GetRecentlyCreatedFolder();
return View(recentFolder);
}
Yes, you can use a model which is not stored in a database at all. Your case sounds like an obvious example.
Model, View, Controller makes database access easily abstractable but doesn't necessitate a database.
As much as I like entity framework I've never loved how most tutorials for MVC seem to marry the two - They are essentially unrelated and I think it really muddies the waters for a lot of programmers new to the framework.
All you need for a model is just a plain old class. Instead of using the dbcontext you'd simply use whatever code you need to load your data.