I'm new to EF Core and I have a problem in this section (Startup.cs):
services.AddDbContext<DataContext>(opt =>
{
opt.UseSqlite(Configuration.GetConnectionString("DefaultConnection"));
});
The DataContext is a .cs file, in the Persistence folder, and it's a class that derives from DbContext.
When I write in above of Startup.cs:
using Persistnece;
using Microsoft.EntityFramewormCore;
Visual Studio Code throws an error :
Remove unnecessary using !?
and when I use
dotnet ef migration add InitialCreate -p Persistence/ -s API/
command, the result is
Build start .. Build failed
What is the problem?
Note: I have downloaded Microsoft.EntityFrameworkCore and Microsoft.EntityFrameworkCore.sqlite
See the error that appears in the screenshot:
Related
I am trying to create a model from an existing database from c# code.
The statements I use are exactly the ones given in the Microsoft documentation at https://learn.microsoft.com/en-us/ef/core/get-started/overview/first-app?tabs=netcore-cli
and I am simply executing them via a process created in c# code.
When executed directly from the command line the entity model is generated correctly for both the db context and the classes for the entities.
When executed via a process from VS2022 the statements run correctly without reporting an error but only the db context is generated, and no classes for the entities are created.
If you run in an empty folder the statements as generated by the code, ie:
dotnet new console
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet ef dbcontext scaffold "Server=***.***.***.***;User Id=******;Password=*********" Microsoft.EntityFrameworkCore.SqlServer -o Model -f -v
and examini the result folder, in the Model folder you will find the dbcontext AND all the entities definitions for the database.
I am confused at this point, and would like to hear from anybody who might have an idea of what is happening.
I created a .Net 5 Web Api project and a library project. In the library project I created a database entity, a context and an extension to register the context on startup
public static IServiceCollection AddContexts(this IServiceCollection services)
=> services.AddDbContext<CarsContext>(x => x.UseNpgsql("Host=host;Database=db;Username=user;Password=pw"));
In the Web Api project I call the AddContexts method in the startup file. With the EF cli I want to generate migrations in the lib project by calling this in the Api directory
dotnet ef migrations add Init --startup-project . -o ./LibProj
The build succeeds but unfortunately I get this error
Your target project 'ApiProj' doesn't match your migrations assembly
'LibProj'. 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("ApiProj")). 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 don't think my Api project should deal with database related things. Is there a way I can fix my command to use the Api project as the startup project but take the context from the lib project and put the migrations into the lib project?
Use the --project flag for the dotnet ef command as well:
dotnet ef migrations add Init --startup-project ./ApiProj --project ./LibProj -o ./LibProj
The --project flag sets the target project. Change the paths for each flag as needed, but I think that should give you what you need.
To run this commands from your library project you can Add packages to your library project:
Microsoft.EntityFrameworkCore.Design
Microsoft.EntityFrameworkCore.SqlServer
After that you can ran ef commands from your library folder and reference it to your ApiProj.
Example:
dotnet ef --startup-project ../ApiProj migrations add init
dotnet ef --startup-project ../ApiProj database update
I have a project with this structure
TooSeeWeb.Infrastructure is for migrations.
When I try to run migrations with this command
dotnet ef migrations add ExampleMigration -s ..\TooSeeWeb
I have this error
Unable to retrieve project metadata. Ensure it's an MSBuild-based .NET Core project. If you're using custom BaseIntermediateOutputPath or MSBuildProjectExtensionsPath values, Use the --msbuildprojectextensionspath option
How I can fix this?
This is 2 years old but I was just in the same situation so it is still relevant. It's first result on Google for this error.
So I can see in your Screenshot that you are not in the standard Windows Visual Studio so I assume you are not on Windows (makes a difference in how to write file paths). Also I can see that you used ..\TooSeeWeb with a backslash.
Solution: Change all \ to a / forward slash so in your case I guess it would be:
dotnet ef migrations add ExampleMigration -s ../TooSeeWeb
For me it was working on Windows but failing on macOS (OS X) with this error:
Unable to retrieve project metadata. Ensure it's an SDK-style project.
If you're using a custom BaseIntermediateOutputPath or
MSBuildProjectExtensionsPath values, Use the
--msbuildprojectextensionspath option.
Additionally it gives the information (that gives a better hint):
MSBUILD : error MSB1009: Project file does not exist.
Here my more complex statement WORKING with forward slashes:
dotnet ef --startup-project ./MainProject.csproj migrations add MyMigration --context MyDbContextPostgreSQL --output-dir Migrations --project ../MyDatabasePostgreSQL/MyDatabasePostgreSQL.csproj
You have to point to your web project
dotnet ef --startup-project ../TooSeeWeb migrations add MigrationName -c NameOfYourDBContext
More details about multi project you can find https://learn.microsoft.com/en-us/ef/core/managing-schemas/migrations/projects
I had the same error. I solved it by including the nuget package:
Microsoft.EntityFrameworkCore.Tools
just add the path to your startup project and database project like this:
dotnet ef database update --verbose --project "src/Services/Discount/Discount.Infrastructure.Rdms" --startup-project "src/Services/Discount/Discount.Web"
The path should be relative to your current directory to the destination directory, for instance, if I change my current directory to /src the path would be Services/Discount/Discount.Infrastructure.Rdms
The problem for me was that the project was in the solution folder so I had to specify the project path like this
dotnet ef migrations add InitialCreate --project SolutionName/ProjectName.csproj
My error was similar, but different. In fact the same error as #CodingYourLife mentions (perhaps the error wording has changed over time, or it is in fact a different error), anyway... This was the error:
Unable to retrieve project metadata. Ensure it's an SDK-style project. If you're using a custom BaseIntermediateOutputPath or MSBuildProjectExtensionsPath values, Use the --msbuildprojectextensionspath option.
It turned out that I needed to run the dotnet ef dbcontext scaffold <list_of_options> command from the parent folder (the one with the solution file in it - not from the PROJECT folder). I used cd .. (to move up one folder) and re-ran the command, and it created my database-context and EF classes for the tables specified.
I don't know how this problems appeared.
But i truly know that most developers come from using these commands:
dotnet ef migrations add "MigrationName" -s ../ProjectName
dotnet ef migrations remove -s ../ProjectName
dotnet ef database update -s ../ProjectName
So replaced them with these:
dotnet ef --startup-project ../ProjectName migrations add
MigrationName -c DbContextName
dotnet ef --startup-project ../ProjectName database update -c
FoodTownDbContext
I think the same apply for this,but haven't tested it:
dotnet ef --startup-project ../ProjectName migrations remove
-c DbContextName
first of all, your need to see the exact context name. This is needed for
dotnet ef migrations add -c <your context name>
You can see your contexts in your project by using this command:
dotnet ef dbcontext list
You will see something like below👇
AspNetCore.Jwt.Sample.Config.MyIntIdentityContext
AspNetCore.Jwt.Sample.Config.MyIdentityContext
See... there is more than one context. Choose© your context's full name and paste it after -c option
dotnet ef migrations add Initial -c AspNetCore.Jwt.Sample.Config.MyIntIdentityContext
use as above☝.
and that is ok! It works well now.
possible reasons:
main reason is your project includes more than one context class
in my case. Context class was in a file with other classes.(i.e.) this config (.cs)file from this impressive github repository
usually I have this problem when I receive updates for dotnet sdks. ProgramFiles/dotnet/sdk.
The problem is that I use an MSBuildSDKsPath system variable and this path doesn't update after dotnet sdk updates.
If you face the same problem, and use the same system variable, that can be the solution.
I am using Entity Framework Core .NET Command-line Tools 6.0.10, and the following worked for me.
Make sure you install the EF tooling globally
dotnet tool install dotnet-ef --global
Make sure you update it to the latest
dotnet tool update dotnet-ef --global
Open a Powershell off your start up project. In your case, it would be TooSeeWeb? Your Powershell should default the root to something like
PS C:\your-user\source\repos\TooSeeWeb\src\TooSeeWeb>
Run the following command to add a migration
dotnet ef migrations add ExampleMigration
-c YourDbContext
-p ../TooSeeWeb.Infrastructure
-o Data/Migrations
-p should set the project where you want the migrations to be put in.
-o is the directory you want to put files in, and it's relative to the project directory you just set with -p.
You can also use -s to set the start up project, where you have your connection string. But since I open the Powershell off the start up, I don't have to specify this, as it defaults to the current working directory.
You can do dotnet ef migrations add -h to see the whole list of optional arguments and what they do.
In my case it was caused by EF versions that I had installed.
I had Entity Framework Core .NET Command-line Tools 7.0.1 installed and the project I was trying to add the migration to, was using EF 6.
Solution was to run EntityFramework6\Add-Migration instead of Add-Migration
I'm trying to create a Code First Entity Framework ASP.NET Core 2 project in Visual Studio Code. I've been following the Create a Web API with ASP.NET Core MVC and Visual Studio Code on Linux, macOS, and Windows tutorial, which uses an in-memory datastore as its DbContext. I'm trying to move this to LocalDB.
The tutorial Getting Started with EF Core on ASP.NET Core with a New database suggests I should be able to do this with a migration.
Once you have a model, you can use migrations to create a database.
Open the PMC:
Tools –> NuGet Package Manager –> Package Manager Console
Run Add-Migration InitialCreate to scaffold a migration to create the initial set of tables for your model. If you receive an error stating The term 'add-migration' is not recognized as the name of a cmdlet, close and reopen Visual Studio.
Run Update-Database to apply the new migration to the database. This command creates the database before applying migrations.
The VS Code equivalent of using the Package Manager Console seems to be:
dotnet ef migrations add InitialCreate
I've added EF's Design namespace with...
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet restore
And have the reference in my csproj:
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.1" />
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
</ItemGroup>
But when I try that the dotnet ef migrations add command afterwards, it acts like the table for my TodoItems model needed to already exist in the database. It was my understanding that the migration would create the tables based on my models.
c:\Projects\TodoApi>dotnet ef migrations add InitialCreate -v
Using project 'c:\Projects\TodoApi\TodoApi.csproj'.
Using startup project 'c:\Projects\TodoApi\TodoApi.csproj'.
Writing 'c:\Projects\TodoApi\obj\TodoApi.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=C:\Users\UserName\AppData\Local\Temp\tmp945E.tmp /verbosity:quiet /nologo c:\Projects\TodoApi\TodoApi.csproj
Writing 'c:\Projects\TodoApi\obj\TodoApi.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=C:\Users\UserName\AppData\Local\Temp\tmp96FF.tmp /verbosity:quiet /nologo c:\Projects\TodoApi\TodoApi.csproj
dotnet build c:\Projects\TodoApi\TodoApi.csproj /verbosity:quiet /nologo
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:02.29
dotnet exec --depsfile c:\Projects\TodoApi\bin\Debug\netcoreapp2.0\TodoApi.deps.json --additionalprobingpath C:\Users\UserName\.nuget\packages --additionalprobingpath "C:\Program Files (x86)\Microsoft SDKs\NuGetPackagesFallback" --additionalprobingpath "C:\Program Files\dotnet\sdk\NuGetFallbackFolder" --runtimeconfig c:\Projects\TodoApi\bin\Debug\netcoreapp2.0\TodoApi.runtimeconfig.json C:\Users\UserName\.nuget\packages\microsoft.entityframeworkcore.tools.dotnet\2.0.0\tools\netcoreapp2.0\ef.dll migrations add InitialCreate --assembly c:\Projects\TodoApi\bin\Debug\netcoreapp2.0\TodoApi.dll --startup-assembly c:\Projects\TodoApi\bin\Debug\netcoreapp2.0\TodoApi.dll --project-dir c:\Projects\TodoApi\ --verbose --root-namespace TodoApi
Using assembly 'TodoApi'.
Using startup assembly 'TodoApi'.
Using application base 'c:\Projects\TodoApi\bin\Debug\netcoreapp2.0'.
Using working directory 'c:\Projects\TodoApi'.
Using root namespace 'TodoApi'.
Using project directory 'c:\Projects\TodoApi\'.
Finding DbContext classes...
Finding IDesignTimeDbContextFactory implementations...
Finding application service provider...
Finding BuildWebHost method...
Using environment 'Development'.
Using application service provider from BuildWebHost method on 'Program'.
Found DbContext 'DatabaseContext'.
Finding DbContext classes in the project...
fail: Microsoft.EntityFrameworkCore.Database.Command[20102]
Failed executing DbCommand (7ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT CASE
WHEN EXISTS (
SELECT 1
FROM [TodoItems] AS [t])
THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END
System.Data.SqlClient.SqlException (0x80131904): Invalid object name 'TodoItems'.
What needs to be done to ensure tables are created based on my models?
The only gotcha I can think of offhand is that I have the connection string inline rather than in appsettings.json, but I'm not sure why that'd be a big deal, unless the migration is looking for a config by default.
public void ConfigureServices(IServiceCollection services)
{
// In memory: services.AddDbContext<DatabaseContext>(opt => opt.UseInMemoryDatabase("TodoList")); // <<< REMOVED
string strCxn = "Server=(localdb)\\mssqllocaldb;Database=Contacts;Trusted_Connection=True;MultipleActiveResultSets=true"; // <<< ADDED
services.AddDbContext<DatabaseContext>(options => options.UseSqlServer(strCxn)); // <<< ADDED
services.AddMvc();
}
Fwiw, those are the only changes I've made to the TodoApi tutorial's code to move from the in-memory db to LocalDB.
Update: Fwiw, I tried changing the database name in the connection string..
string strCxn = "Server=(localdb)\\mssqllocaldb;Database=Contacts2;Trusted_Connection=True;MultipleActiveResultSets=true";
(Changing Contacts to Contacts2, just in case it thought that, since it found the Contacts db initially, a migration had already taken place...)
That didn't work either, though the error changed in a way that suggests the connection string is working and being read.
Cannot open database "Contacts2" requested by the login. The login failed.
Login failed for user 'COMPUTER-NAME\UserName'.
As part of the DbContext's constructor, I was seeding data...
public class DatabaseContext : DbContext {
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options)
{
this.MinimallySeedDatabase();
}
public void MinimallySeedDatabase()
{
State NY = this.States.Where(s => s.Abbr.Equals("NY")).FirstOrDefault();
if (null == NY)
{
NY = new State {
Name = "New York",
Abbr = "NY"
};
this.States.Add(NY);
this.SaveChanges();
}
// etc etc etc...
}
public DbSet<Contact> Contacts {get; set;}
public DbSet<Address> Addresses {get; set;}
public DbSet<AddyType> AddyTypes {get; set;}
public DbSet<State> States {get; set;}
}
Part of the migration's execution involves instantiating the DbContext obviously before the tables for the DbSets are migrated over. Since the constructor, in this example, requires accessing States, and because the migration hasn't gotten to the point it's created the States table to pull from yet, the migration blows up.
As Kirk mentions, if I take out the seeding, I'm fine. And if you want to seed, you need to move that somewhere other than the constructor, even though the seeding in the constructor works fine outside of a migration attempt/in normal Kestrel testing.
For me, I just commented out this.MinimallySeedDatabase(); when I ran the migration.
Following this Microsoft Tutorial when I run the PM> Add-Migration MyFirstMigration command in VS2015 project created from the same tutorial I get the following error that I can't resolve:
More than one DbContext was found. Specify which one to use.
Use the '-Context' parameter for PowerShell commands and the
'--context' parameter for dotnet commands.
Point to note
I'm using the above tutorial with the exception that I'm using Individual User Account authentication instead of No Authentication used in the tutorial.
I've latest release of ASP.NeT Core 1.0 and VS2015-Update 3 on windows 8.1
This is a freshly created project. No other DbContext was manually installed
Running the following command (obtained from this article) and a response from #Maverik (from StackOverflow here) and a suggestion from #doctor above helped me resolved the issue. Thank you all for your help:
PM> Add-Migration MyFirstMigration -Context BloggingContext
The error clearly explains to mention --context with db Context name if more than one DbContext. So try by mentioning your DbContext name.
dotnet ef migrations add Initial --context SampleDbContext
Hope this helps.
If you need only update a identity schema existent, try it:
update-database -Context ApplicationDbContext
ApplicationDbContext = your identity context
that because you have two DbContext in your solution. First is default created when you creating project(ApplicationDbContext) and second your EF DbContext.
Solution is described in error message just specify your EF DbContext
Add-Migration MyFirstMigration -Context DbContextName
It does work in my project.
Use below to commands:
PM> Add-Migration MyFirstMigration -Context YourDbContext
PM> update-database -Context YourDbContext
[--context]
The DbContext class to use. Class name only or fully qualified with
namespaces. If this option is omitted, EF Core will find the context
class. If there are multiple context classes, this option is required.
Add-Migration MyMigration -context DataContextName