All my searches are coming back to the same one of two issues, which aren't the problem in this project. I've never had trouble with this before, but this particular project is being weird.
First off, the project name is Site. The class SiteContext inherits DbContext.
When I run Enable-Migrations, even explicitly , the Package manager console returns an error:
PM> Enable-Migrations -ContextType SiteContext
The context type 'SiteContext' was not found in the assembly 'Site'.
But it's right there in the code:
// Not in a namespace or anything
public class SiteContext : DbContext {
// public DbSets in here
}
I can use SiteContext anywhere in my site's code, access the database though an object of it, etc. It's only the Enable-Migrations command that can't find it. Other than this, Entity's code-first functionality is working properly.
Any ideas what might be going on? Where did I mess this up?
(Entity Framework 6.0.2 / Web Pages 3.1.1)
ASP.NET Web Pages sites are built using the Web Site project type. This project type doesn't support Entity Framework Migrations. If you want to use Code First Migrations with an ASP.NET Web Pages site, you need to develop your data access code as a separate class library. That project type does support EF Migrations. I've blogged about it here: http://www.mikesdotnetting.com/Article/217/Code-First-Migrations-With-ASP.NET-Web-Pages-Sites
Instead of -ContextType, use -ProjectName and Specify Site.
Edit: First, try -ContextTypeName. I have to assume you didn't.
Related
I have a solution with the following projects:
ASP.NET Core MVC website
ASP.NET Core Web API
DAL [incl DbContext and model classes]
Both the website and API reference the DAL and can use it's dbContext and model classes.
Both these projects have an appsettings.json file with the connection string and DB access is all working.
I can't how ever work out how to add migrations.
If I set the default project to the DAL project, I get this error:
Unable to create an object of type 'myDbContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
If I set it to the Api or website, I get:
Your target project 'website' doesn't match your migrations assembly 'DAL'. Either change your target project or change your migrations assembly.
Change your migrations assembly by using DbContextOptionsBuilder. E.g. options.UseSqlServer(connection, b => b.MigrationsAssembly("website")). By default, the migrations assembly is the assembly containing the DbContext.
Change your target project to the migrations project by using the Package Manager Console's Default project drop-down list, or by executing "dotnet ef" from the directory containing the migrations project.
I can find information on how to set up a separate class lib for the dbcontect and models for .NET Core 3.1 but I am struggling with .NET 6.
I have tried to follow this tutorial
https://garywoodfine.com/using-ef-core-in-a-separate-class-library-project/
But it's not the same as .net 6 so I cant follow it as I get errors when I try and create the DBContextFactory towards the bottom. The SetBasePath is not a definition within ConfigurationBuilder. I'm not fluent enough with .NET Core to work out whats required.
I have the exact same setup as you have with a website, api and a DAL layer.
This is how I register the DbContext in the website and in the api program.cs:
builder.Services.AddDbContext<AppDbContext>(
options => options.UseSqlServer(config.ConnectionString, sqlOptions => {
sqlOptions.MigrationsAssembly("App.Entities");}));
This is how the AppDbContext is created in the DAL project:
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
{ }
// Your DbSet entities here
}
Then when you run your first migration command "Add-Migration" you need to select the DAL project in the package manager console dropdown and it should automatically create the migration folder with the migration files.
You need to have the following packages installed in the DAL project:
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Tools
Honestly, one would need more information to narrow down the problem.
I think there are two possible problems.
You are not using the exact DB Context in the program.cs of the two project in the presentation layer(MVC and API).
You have updated the migration the migration on API or MVC, or you have made changes to the database hence the comparison is not as clear.
How to resolve:
Make sure that database connection string in the two application.json
is same
Make sure that in the Program.cs of the the API and the MVC, that you have added the exact dbcontext from DAL "and is identical".
Make sure you have uniform Nugget package across the solution for the EF tool, Server, Design
Make sure the Models in the last migration mirrors what is obtainable in the database.
Make sure that the Package Manager console is has DAL selected as the default project, while the startup project which can be MVC or API is not having any errors.
Make sure that there is a dbSet<> in the dbContext in DAL before adding a migration
I have a web api project "Reactivities" and another project "Persisitence" to place my DbContext. When I try to use my add-migration in the Reactivities, using this syntax in the console add-migration InitalCreate -Context .\Persistence I get this error:
No DbContext named '.\Persistence' was found.
Even if I use add-migration InitialCreate -Context .\Persistence\DataContext still I get the same error,
This is in my startup class in Reactivities
services.AddDbContext<DataContext>(opt =>
{
opt.UseSqlite(Configuration.GetConnectionString("DefaultConnection"));
});
How can I correct this?
You have to do migration work in a project that instantiates the dbcontext, in my case I have created a dbmigrator project with a class that inherits the
IDesignTimeDbContextFactory<T>
where T is the dbcontext type.
This allows me to have a project that has the dbcontexts, a project that works with migrations and a project that uses the dbcontexts independently of each other.
This guide shows you how to use the interface i mentioned:
https://codingblast.com/entityframework-core-idesigntimedbcontextfactory/
I have a project call RemoteWork where i have my Dbcontext. I have 2 models inside the DbContext - USER and PRODUCTS. I was using code first approach. I then used the "add-migration" and it was successful. I then referenced the Remotework in another project call Apiclient. They are both in the same solution. Now I have altered my table in USER and so it was out of sync. I wanted to make it to be in sync. I have tried different methods i have read online, I was getting different error messages. Can anyone please help in this regard.
I have done this: Add-Migration SecondMigration
This is the error message:
No DbContext was found in assembly 'AppClient'. Ensure that you're using the correct assembly and that the type is neither abstract nor generic.
Please note that AppClient was made as the startup project. I have also tried making remotework as a start up project, it did not resolve it either:
PM> Add-Migration SecondMigration
No DbContext was found in assembly 'AppClient'. Ensure that you're using the correct assembly and that the type is neither abstract nor generic.
PM> Add-Migration -Name MyMigration -OutputDir MyMigrationDir -Context BettingDbContext -Project RemoteWork -StartupProject AppClient
I wanted the models to be in sync with my database
I assume you are running add-migration from the package manager console in visual studio.
Either make sure you have selected the project that contains your context in the "Default project" dropdown at the top of the package manager console. Or use the -StartUpProjectName argument on add-migration.
I have a clean project solution (intended to be a .NET Core MVC app)
I have two projects - Home.CorePoC.EntityModel and Home.CorePoC.Model
I am calling dotnet cli from Home.CorePoC.Model.
The idea is that I want partial classes and logical separation from custom attributes and attributes from database.
I want to write a PowerShell script that I will be calling when I want to add/remove some tables, columns in tables etc.
In dotnet CLI when I add initially tables, it works just fine:
Scaffold-DbContext "Server=sqlServ2016;Database=TestDb;Persist Security
Info=False;User ID=admin;Password=admin;" Microsoft.EntityFrameworkCore.SqlServer
-Tables "Table1","Table2","Table3" -ContextDir "..\Home.CorePoC.EntityModel"
-OutputDir "TestDB" -force -DataAnnotations -UseDatabaseNames
Now, when I want to add just more tables it work as well but I have an error message: "Cannot add 'Table4'. There is already a linked file in this folder with the same name."
Also, I get error in cli console:
Exception calling "AddFromFile" with "1" argument(s): "A drag operation is already in progress (Exception from HRESULT: 0x80040103)"
Must I delete all files and then recreate it (linked file TestContext.cs that was initially created) or there is different way how to avoid this error message which is non-critical (I successfully added Table4 to my models).
I am planning to put this statement into PowerShell script which it will be called from project folder (where I have installed nuget Microsoft.EntityFrameworkCore.Tools(2.1.4))
That is because it will try and add the Context file for Table4 but is unable to as one already exists. There is already a feature request to update Entity Framework Core scaffolds rather than having to recreate them every time. You would have to override the generated entities each time by using the -Force flag
I have looked at other questions on SO and on blogs and official MS docs but I can't find the proper way.
What I am trying to achieve:
Deploy version 1 of an MVC website with SQL DB (code is based on Entity Code First v. 6.1), without any concept of migration because it's DB SCHEMA v.1
Deploy further versions (2, 3, ..) with automatic migration to SCHEMA v2 (and then v3 etc.) and without running Update-Database in Package Manager console
So, following MS tutorial (i.e. https://msdn.microsoft.com/en-gb/data/jj591621.aspx) version 1 creates tables for Schema v1:
Blogs table with two columns (BlogId and Name)
__MigrationHistory with one row (MigrationId contains InitialCreate). Not sure what this is about, but I guess it's the initial schema. Am I right?
Then I open Package Manager Console and I type: Enable-Migrations which creates classes for migration (201610091823367_InitialCreate.cs and Configuration.cs). I then modify the Blog class to have a new property Url as suggested in the tutorial and run Add-Migration AddBlogUrl, which creates 201610091830008_AddBlogUrl.cs
In addition, I added
Database.SetInitializer(new MigrateDatabaseToLatestVersion<BlogContext, Configuration>());
to the main, so when the application starts it should migrate automatically.
I launch the app v2, and everything is working perfectly. The Table has now the new column.
When I launch the app v2 again, it crashes with exception:
Unhandled exception: System.Data.SqlClient.SqlException: There is already an object named 'Blogs' in the database. and all the related stack trace.
So it looks like it's not recognizing that it's in the DB there's the most recent schema, so it tries to create the table again. I have added a breakpoint to InitialCreate class, method Up and it is called. I am surprised!
I've tried also a different approach:
ran app v1
ran app v2b with AutomaticMigrationsEnabled = true; in the Configuration class. The outcome is the same.
Can anyone help me to understand what's wrong and what's the right approach?
Can you confirm that in the meantime I am OK to deploy SCHEMA v1 without having enabled migrations at all?
I was hoping that this kind of scenarios were covered by Entity.