I have a code first model, e.g.:
public class Cars
{
public int Id { get; set; }
public string Brand { get; set; }
}
My DBContext looks like this:
public class TestDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("Data Source = data.db");
}
DbSet<Car> Cars { get; set; }
}
Now when I call "context.Database.Migrate" a _EFMigrationHistory table gets created but no migrations are happening. No tables or columns get created.
And when I call "update-database" in the command line it says "No migrations were applied. The database is already up to date." although there is a "Cars" table to add
What am I doing wrong?
It appears you might have forgotten to create your first migration. Every time you change your object model in a way that needs applied to the database,
you'll need to create a migration - this is not automatic so you can customize the migration code if needed and batch multiple changes into one logical group.
In the package manager console (command line), set your default project to whatever project houses your TestDbContext, and run the add-migration command with a name for the migration, then your project will have a migration to run:
PM> add-migration MyInitalMigration
Package Manager Console Example Image
Related
I first time trying to create web app (.net core 2.1) from scratch with Entity Framework. For some reason I can't get DB generated.
So I installed EF nuget. And did next things:
Added class that inheres from DbContext:
public class ApplicationDbContext:DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<Server> Servers { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Server>().HasData(
new Server
{
Name = "My Server",
InUse = false
}
);
}
}
And created Entity:
public class Server
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
public bool InUse { get; set; }
}
In startup.cs in ConfigureServices method I added:
var connectionString = Configuration.GetConnectionString("ApplicationConnection");
services.AddDbContext<ApplicationDbContext>
(options => options.UseSqlServer(connectionString));
Connection string coming from appsettings and I debugged it so it does coming through, and it same string that I using in other projects with just different Database name value and it should be ok.
Also I run from console Add-Migration command so I got Migrations folder with InitialCreate migration and some snapshot file.
But when I run app I don't get any error but it never hit break point inside InitialCreate.cs migration and so never create DB.
Any ideas where and what should I call to trigger those?
If you want entity framework automatically creates your database
In Configuration file, add this line in constructor:
AutomaticMigrationsEnabled = true;
Then add the code into DBContext:
Database.SetInitializer(new
DropCreateDatabaseAlways<YourDbContext>());
Then when the application already ran:
Database.SetInitializer(new
DropCreateDatabaseIfModelChanges<YourDbContext>());
You can also have a look MigrateDatabaseToLatestVersion
If you manually track version of database:
Update AutomaticMigrationsEnabled = false;
From console, run command Update-Database to migrate your database
manually
So I been able to create DB by adding next code inside Startup.cs in Configure() method
using (var scope = app.ApplicationServices.CreateScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
dbContext.Database.Migrate();
if (!dbContext.Servers.Any())
{
dbContext.Servers.Add(new Server
{
Name = "My Server",
InUse = false
});
dbContext.SaveChanges();
}
}
I have developed a new asp.net Core web application using Visual Studio 2015. I am at the point where I am adding user customization options by adding additional tables to my local database. However I have been unable to add whatever EF needs to query a new table correctly. I get the following error when attempting to query the table..
Applying existing migrations for ApplicationDbContext may resolve this issue
There are migrations for ApplicationDbContext that have not been applied to the database
•00000000000000_CreateIdentitySchema
Apply Migrations
In Visual Studio, you can use the Package Manager Console to apply pending migrations to the database:
PM> Update-Database
Alternatively, you can apply pending migrations from a command prompt at your project directory:
dotnet ef database update
My table is a simple table with a few varchar or nvarchar columns. The model looks something like...
namespace MyNamespace.ColorSchemes
{
public class ColorSchemesViewModel
{
[Required]
public string Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string bc { get; set; }
}
Table looks something like this in SQL Server...
CREATE TABLE [dbo].[ColorSchemes](
[Id] [nvarchar](50) NOT NULL,
[Name] [varchar](32) NOT NULL,
[bc] [nchar](7) NOT NULL
)
I have added the table to the application context like such...
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public DbSet<ColorSchemesViewModel> Colors { get; set; }
I have also used as separate class similarly like..
public DbSet<ColorSchemes> Colors { get; set; }
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Customize the ASP.NET Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
}
}
I have added the context to a controller like this...
private ApplicationDbContext _context;
public MyController(IMemoryCache memoryCache, ILoggerFactory loggerFactory, ApplicationDbContext context)
{
_memoryCache = memoryCache;
_logger = loggerFactory.CreateLogger<ChordMVCController>();
_context = context;
}
I have tried to query the table in my controller like this...
var colorSchemes = (from c in _context.Colors
select c).ToList();
I have attempted to use the Package Manager to per instructions from the error...
PM> Update-Database
I always get this error...
System.Data.SqlClient.SqlException: There is already an object named 'AspNetRoles' in the database.
This doesn't make sense since this table is already in the database and the EF definition. How do I get my table added properly to the EF migrations so I can query it?
I was able to solve this myself...
I created a different context rather than trying to embed the dbset in the default ApplicationDbContext and also removed the onModelCreating method.
public class ColorSchemeDbContext : DbContext
{
public ColorSchemeDbContext(DbContextOptions<ColorSchemeDbContext> options) : base(options)
{
}
public DbSet<ColorScheme> ColorSchemes { get; set; }
}
Replaced the ApplicationDBContext with the new context in my controller class...
private readonly ColorSchemeDbContext _context;
public MyController(IMemoryCache memoryCache, ILoggerFactory loggerFactory, ColorSchemeDbContext context)
{
_memoryCache = memoryCache;
_logger = loggerFactory.CreateLogger<ChordMVCController>();
_context = context;
}
After that the query worked. I spent a lot of time attempting to use the EF migrations to create the tables from a class syntax. Nothing seemed to work. I was creating a new .NET CORE web application in VS 2015 with the template and using user authentication which creates the AspNetRoles tables in SqlLite once you do an update-database. It is very confusing how to add additional tables using a code first approach after that. A lot more documentation is needed regarding EF migrations with respect to managing projects over time. I see the benefits of having all of your database updates maintained from your VS project but it is not easy to understand.
I am using entity framework 6.1. I used code-based migration i.e. Migrate.exe to update my database (Add a new property to table). Migrate.exe executed fine and I did refresh on my SQL Server database but the newly added column was not visible.
I inserted a row into the table and checked table and found that now newly column is added to the table.
I would like to know why this newly created column not visible immediately after executing migrate.exe and why I have to hit database to see my update model changes?
Please respond.
I have used below database context and initializer.
public class AMLDBContext : DbContext
{
public DbSet<Template> Templates { get; set; }
public DbSet<Property> Properties { get; set; }
public AMLDBContext()
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<AMLDBContext, Migrations.Configuration>());
}
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Property>().HasKey(s => new { s.PropertyName, s.TemplateId });
modelBuilder.Entity<ReturnAttribute>().HasKey(s => new { s.AttributeName, s.TemplateId });
base.OnModelCreating(modelBuilder);
}
}
I used below command for migrate.exe.
migrate.exe AutoDbUpgrade.exe /StartUpDirectory:"C:\TestProject\AutoDbUpgrade\AutoDbUpgrade\bin\Debug" /startupConfigurationFile=”AutoDbUpgrade.exe.config” /verbose
I am developing an MVC project using code first. I create my database using code first as you can see here :
public class DataContext:DbContext
{
public DataContext()
: base("DefaultConnection")
{
this.Configuration.LazyLoadingEnabled = false;
this.Configuration.ProxyCreationEnabled = false;
Database.SetInitializer(
new MigrateDatabaseToLatestVersion<DataContext, MigrationsConfiguration>()
);
}
public DbSet<Member> Members { get; set; }
public DbSet<Traffic> Traffics { get; set; }
public DbSet<Car> Cars { get; set; }
public DbSet<Validation> Validations { get; set; }
public DbSet<Log> Logs { get; set; }
public DbSet<File> Files { get; set; }
}
I uploaded my project in the company server, and they used my project and entered some values to database, so after sometimes I changed some columns in database, and I added normally in SQL design to database table, so I changed some part of my code too, and now then I upload my published file I get this error :
There is already an object named 'Cars' in the database.
Note: I can't delete the database because I have data in it ,as i said I added the new columns to database, but my application can't connect to that database .
Migration part:
public class MigrationsConfiguration : DbMigrationsConfiguration<DataContext>
{
public MigrationsConfiguration()
{
this.AutomaticMigrationDataLossAllowed = true;
this.AutomaticMigrationsEnabled = true;
}
}
As you've got data in your production database already, don't use automatic migrations. Your first priority is to get your databases in sync with your model. How you do this will depend on how complicated your model is, e.g. how many tables. My suggestion would be:
Disable Automatic migrations
Point your dev copy at a blank database, and create an initial migration
Run Update-Database -Script to generate an SQL script for the migration
Alter the script by hand so that it can be run on your production database
Run this on your production database
Once you've got to this point, make sure you add migrations each time you want to make changes to your model, rather than making them by hand.
I have a application using code first; in search section I have to gather information from 3 tables and their related tables so I made a view; and since there is no syntax for code first to create view (I think so; please let me know if I'm wrong) I used pure SQL script;
on model creating to prevent EF to create a table with same name as table (VIEW_SEARCH) I did :
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Ignore<View_Search>();
}
any ways application works fine until you try to get data from the view then BANG...
The model backing the 'SearchContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269)
This error simply says that what you have in your model file is inconsistent with what you have in your database.
To make it consistent go to Package Manager Console and type Enable-Migrations, then Add-Migration yourMigrationName and Update-Database. The error should disappear.
If you want to combine data from 3 tables you can simply create a ViewModel.
Let's say you have 3 models: Book, Author, BookStore and you want to have all information in one view. You create ViewModel
public class MyViewModel
{
public Book myBook {get; set;}
public Author myAuthor {get; set;}
public BookStore myBookStore {get; set;}
}
Then you add at the top of your all-in-one-view
#model myNamespace.MyViewModel
and access items like
Model.Book.title
Model.Author.name
Model.BookStore.isClosed
I'm actually working with Entity Framework "Code First" and views, the way I do it is like this:
1) Create a class
[Table("view_name_on_database")]
public class ViewClassName {
// View columns mapping
public int Id {get; set;}
public string Name {get; set;}
// And a few more...
}
2) Add the class to the context
public class ContextName : DbContext {
// Tables
public DbSet<SomeTableClassHere> ATable { get; set; }
// And other tables...
// Views
public DbSet<ViewClassName> ViewContextName { get; set; }
// This lines help me during "update-database" command
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
// Remove comments before "update-database" command and
// comment this line again after "update-database", otherwise
// you will not be able to query the view from the context.
// Ignore the creation of a table named "view_name_on_database"
modelBuilder.Ignore<ViewClassName>();
}
}