Quando utilizzo asp.net core ed ef core, non ho alcun problema a invocare add-migration init
. Ma quando applico lo stesso approccio su un'applicazione console di seguito, viene visualizzato un errore che dice:
Impossibile creare un oggetto di tipo "StudentContext". Aggiungi un'implementazione di 'IDesignTimeDbContextFactory' al progetto o vedi https://go.microsoft.com/fwlink/?linkid=851728 per ulteriori schemi supportati in fase di progettazione.
Qual è il modo più semplice per risolvere questo problema?
Il progetto dell'applicazione console .net core è il seguente:
{
"ConnectionStrings": {
"Storage": "Data Source=storage.db"
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
</ItemGroup>
</Project>
namespace EFCore.Models
{
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
}
}
using Microsoft.EntityFrameworkCore;
namespace EFCore.Models
{
public class StudentContext : DbContext
{
public StudentContext(DbContextOptions<StudentContext> options) : base(options) { }
public DbSet<Student> Students { get; set; }
}
}
using EFCore.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System.IO;
namespace EFCore
{
class Program
{
static void Main(string[] args)
{
var configurationBuilder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
IConfigurationRoot configuration = configurationBuilder.Build();
string connectionString = configuration.GetConnectionString("Storage");
DbContextOptionsBuilder<StudentContext> optionsBuilder = new DbContextOptionsBuilder<StudentContext>()
.UseSqlite(connectionString);
using (StudentContext sc = new StudentContext(optionsBuilder.Options))
{
sc.Database.Migrate();
sc.Students.AddRange
(
new Student { Name = "Isaac Newton" },
new Student { Name = "C.F. Gauss" },
new Student { Name = "Albert Einstein" }
);
sc.SaveChanges();
}
}
}
}
Dopo aver lottato per diverse ore, ho trovato la soluzione come segue:
using EFCore.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;
using System.IO;
namespace EFCore
{
class Program : IDesignTimeDbContextFactory<StudentContext>
{
public StudentContext CreateDbContext(string[] args)
{
var configurationBuilder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
IConfigurationRoot configuration = configurationBuilder.Build();
string connectionString = configuration.GetConnectionString("Storage");
DbContextOptionsBuilder<StudentContext> optionsBuilder = new DbContextOptionsBuilder<StudentContext>()
.UseSqlite(connectionString);
return new StudentContext(optionsBuilder.Options);
}
static void Main(string[] args)
{
Program p = new Program();
using (StudentContext sc = p.CreateDbContext(null))
{
sc.Database.Migrate();
sc.Students.AddRange
(
new Student { Name = "Isaac Newton" },
new Student { Name = "C.F. Gauss" },
new Student { Name = "Albert Einstein" }
);
sc.SaveChanges();
}
}
}
}
Spero sia utile anche per gli altri!