Cela semble être un problème qui a déjà été résolu , du moins pour les bases de données SQLite.
Ma solution consiste en 3 projets:
J'ai installé les packages suivants dans le projet WPF principal:
Microsoft.EntityFrameworkCore.Tools
Microsoft.EntityFrameworkCore.Design
Les projets 2 et 3 sont référencés dans mon projet principal WPF. Donc, fondamentalement, cela devrait suffire à l'EF pour résoudre les DbContextes.
Cependant, ce n'est pas le cas - car l'exécution de Add-Migration
sur mon projet WPF a pour résultat:
PM> Add-Migration "Initial"
No DbContext was found in Assembly 'TestWPFProject'. Ensure that you're using the correct Assembly and that the type is neither abstract nor generic.
Le passage au projet 3
par défaut dans la console du gestionnaire de packages a pour résultat:
PM> Add-Migration "Initial"
Unable to create an object of type 'ClientDbContext'. Add an implementation of 'IDesignTimeDbContextFactory<ClientDataStoreDbContext>' to the project, or see https://go.Microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time.
Comment utiliser correctement les migrations EF Core avec mon projet de bibliothèque de classes et mon projet WPF?
J'ai reproduit votre solution et trouvé ... une solution :)
Approfondissons.
Nom: ClassLibrary1.
Type: bibliothèque de classes .NET Standard 2.0.
Dépendances: aucune.
Dans ma solution de test, il ne contient qu'une seule classe, un modèle appelé Person.
Person.cs
namespace ClassLibrary1
{
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
}
}
Nom: EFClassLibrary.
Type: bibliothèque de classes .NET Standard 2.0.
Dépendances:
Ce projet, dans ma solution de test, contient une seule classe: le contexte de la base de données.
ClientDbContext.cs
using ClassLibrary1;
using Microsoft.EntityFrameworkCore;
namespace EFClassLibrary
{
public class ClientDbContext : DbContext
{
const string connectionString = "Server=(localdb)\\mssqllocaldb;Database=ClientDb;Trusted_Connection=True;";
public ClientDbContext() : base() { }
public ClientDbContext(DbContextOptions<ClientDbContext> options) : base(options) { }
public DbSet<Person> People { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(connectionString);
}
}
}
Dans cette classe, a défini et utilisé la chaîne de connexion pour se connecter à la base de données (en supposant que c'est LocalDb SQL Server). Si vous souhaitez placer la chaîne de connexion dans un fichier de configuration, vous pouvez ajouter un fichier de configuration partagé à votre solution, puis référencer ce fichier dans votre fichier App.config
(pour plus d'informations, consultez cette page )
Pour pouvoir ajouter des migrations sur ce projet sans définir d'autres projets comme projet de démarrage, vous devez définir le cadre cible. Faites un clic droit sur le projet et cliquez sur l'entrée Edit EFClassLibrary.csproj. Au-dessous de la ligne <TargetFramework>netstandard2.0</TargetFramework>
, vous devez ajouter une autre ligne indiquant le cadre que vous souhaitez cibler. Pour cibler le .NET Framework 4.7, vous devez ajouter
<TargetFramework>net47</TargetFramework>
Vous trouverez une liste de toutes les valeurs autorisées ici .
Mon EFClassLibrary.csproj ressemble au code ci-dessous après avoir ajouté le .NET Framework 4.7 comme cible.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFramework>net47</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.1.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ClassLibrary1\ClassLibrary1.csproj" />
</ItemGroup>
</Project>
Vous êtes maintenant prêt à ajouter votre première migration. Ouvrez la console du gestionnaire de packages et définissez comme projet par défaut le EFClassLibrary. Définissez également ce projet en tant que projet de démarrage (cliquez avec le bouton droit de la souris sur le projet et cliquez sur l'entrée Définir comme projet de démarrage).
Type
PM> Add-Migration Initial
puis
PM> Update-Database
Nom: WpfApp1.
Tapez: application WPF à l'aide de .NET Framework 4.7.
Dépendances:
Dans ce projet, je n'ai ajouté aucun fichier. A vient de modifier le fichier MainWindow.xaml.cs
pour vérifier que tout fonctionne correctement.
MainWindow.xaml.cs
using ClassLibrary1;
using EFClassLibrary;
using System.Windows;
namespace WpfApp1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var db = new ClientDbContext();
db.People.Add(new Person()
{
Name = "Omar"
});
db.SaveChanges();
}
}
}
J'espère que ça aide :)
Ce que Microsoft suggère ici est de créer une nouvelle bibliothèque de classes pour les migrations, puis de déplacer vos fichiers de captures instantanées de modèles et vos migrations vers la nouvelle bibliothèque de classes.
Si vous n'en avez pas ajouté, ajoutez-en un au projet DbContext puis déplacez-le.
Puis configurez la migration Assembly:
options.UseSqlServer(
connectionString,
x => x.MigrationsAssembly("MyApp.Migrations"));
Et ajoutez ensuite une référence à votre Assemblée de migration à partir de votre Assemblée de démarrage:
Remarque:
Si cela provoque une dépendance circulaire, mettez à jour le chemin de sortie de la bibliothèque de classes:
<PropertyGroup>
<OutputPath>..\MyStarupProject\bin\$(Configuration)\</OutputPath>
</PropertyGroup>
pour une deuxième référence, utilisez Le guide de Ben Cull sur la migration EntityFramework Core pour les projets de bibliothèque de classes.
Dans votre projet de démarrage, vous devez créer une fabrique qui implémentera IDesignTimeDbContextFactory et créera le DBContext pour vous.
public class DBContextFactory : IDesignTimeDbContextFactory<DBContext>
{
public DBContext CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<DBContext>();
// Row numbers for paging adds support for old SQL server 2005+. See more:
// https://docs.Microsoft.com/en-us/ef/core/api/Microsoft.entityframeworkcore.infrastructure.sqlserverdbcontextoptionsbuilder
optionsBuilder.UseSqlServer("Server=localhost;Database=DatabaseName;Trusted_Connection=True;MultipleActiveResultSets=true;Integrated Security=SSPI", x => x.UseRowNumberForPaging());
return new DBContext(optionsBuilder.Options);
}
}
Ce qui a fonctionné pour moi, c’est de faire vos tâches habituelles sur votre interface utilisateur côté démarrage.s
services.AddDbContext<ShentonEvaDbContext>(options =>
options.UseSqlServer(
_configuration.GetConnectionString("DevelopmentConnection")));
Ensuite, sur votre configuration DBContext, ajoutez simplement un constructeur
public ShentonEvaDbContext(DbContextOptions<ShentonEvaDbContext> options) : base(options)
{
}
Après cela, sur la console de votre gestionnaire de packages, exécutez simplement la commande suivante:
dotnet ef migrations add InitialMigration --project "NameOfDbContextProject" --startup-project "NameOfWebUIProject"
Ensuite, Everytihng a été ajouté et fait de même pour la mise à jour de la base de données.