问题描述
当我使用实体框架时,我有一个简单的WPF Net Core应用程序,我具有DbContext,但是当我添加迁移时,我会收到错误:
I have simple WPF Net Core app when i'm using entity framework, i have DbContext, but when i have add migration then i receive error:
PM> add-migration init
Build started...
Build succeeded.
Unable to create an object of type 'AppDbContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
我的appsettings.json
my appsettings.json
{
"ConnectionStrings": {
"SqlConnection": "Server=DESKTOP-K6R1EB3\\tester;Database=test;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
AppDbContext
AppDbContext
using Microsoft.EntityFrameworkCore;
namespace WpfApp1
{
public class AppDbContext : DbContext
{
public DbSet<Person> Person { get; set; }
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
{
}
}
}
App.xaml.cs
App.xaml.cs
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.IO;
using System.Windows;
namespace WpfApp1
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
public IServiceProvider ServiceProvider { get; private set; }
public IConfiguration Configuration { get; private set; }
protected override void OnStartup(StartupEventArgs e)
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
Configuration = builder.Build();
var serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);
ServiceProvider = serviceCollection.BuildServiceProvider();
var mainWindow = ServiceProvider.GetRequiredService<MainWindow>();
mainWindow.Show();
}
private void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AppDbContext>
(options => options.UseSqlServer(
Configuration.GetConnectionString("SqlConnection")));
services.AddTransient(typeof(MainWindow));
}
}
}
当然我有简单的模型用于数据库
Of course i have simple model for database
namespace WpfApp1
{
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
}
}
怎么了?我搜索解决方案,但未找到任何结果。早期,我在网络核心和实体框架中编写网络应用,但我没有任何问题。这是我的第一个WPF Net Core应用程序,我对EF配置有问题。
What is wrong? I search solution but i nothing found. Early i write web app in net core and entity framework, and i don't have any problem. This is my first WPF Net Core App, and i have problem with EF configuration.
推荐答案
i能够重现您的问题,并且
i was able to reproduce your issue and get past it.
我以前遇到过这个问题。这篇文章引导我完成了我需要做的事情,对此我感到非常感谢:
i've ran into this before. this article guided me through what i needed to do, very thankful for it: https://blog.tonysneed.com/2018/12/20/idesigntimedbcontextfactory-and-dependency-injection-a-love-story/
:。特别是本节,我们可以使用一些鸭子类型并提供Microsoft.EntityFrameworkCore.Tools将用于创建迁移的类,实现 IDesignTimeDbContextFactory< T>
。
from the article in the error message: https://go.microsoft.com/fwlink/?linkid=851728. specifically this section https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dbcontext-creation#from-a-design-time-factory, we can use some duck typing and provide a class that Microsoft.EntityFrameworkCore.Tools will use to create the migrations, implementing IDesignTimeDbContextFactory<T>
.
tony sneed这篇文章提供了一个通用的抽象实现,然后我们可以非常简单地导出它。
tony sneed's article provides a generic abstract implementation, which we can then derive very simply.
这是通用的抽象实现(编辑,抱歉,我意识到我复制粘贴了我对托尼(Tony)嘲笑我之前遇到过的代码):
here is the generic abstract implementation (edit, sorry, just realized i copy-pasted my adaptation of tony sneed's code that i'd used when i ran into this before):
public abstract class DesignTimeDbContextFactoryBase<TContext> : IDesignTimeDbContextFactory<TContext> where TContext : DbContext
{
public TContext CreateDbContext(string[] args)
{
return Create(Directory.GetCurrentDirectory(), Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));
}
protected abstract TContext CreateNewInstance(DbContextOptions<TContext> options);
public TContext Create()
{
var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var basePath = AppContext.BaseDirectory;
return Create(basePath, environmentName);
}
TContext Create(string basePath, string environmentName)
{
var builder = new ConfigurationBuilder()
.SetBasePath(basePath)
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{environmentName}.json", true)
.AddEnvironmentVariables();
var config = builder.Build();
var connstr = config.GetConnectionString("default");
if (string.IsNullOrWhiteSpace(connstr) == true)
throw new InvalidOperationException("Could not find a connection string named 'default'.");
return Create(connstr);
}
TContext Create(string connectionString)
{
if (string.IsNullOrEmpty(connectionString))
throw new ArgumentException($"{nameof(connectionString)} is null or empty.", nameof(connectionString));
var optionsBuilder = new DbContextOptionsBuilder<TContext>();
Console.WriteLine($"MyDesignTimeDbContextFactory.Create(string): Connection string: {connectionString}");
optionsBuilder.UseSqlServer(connectionString, s => s.CommandTimeout((int)TimeSpan.FromMinutes(10).TotalSeconds));
DbContextOptions<TContext> options = optionsBuilder.Options;
return CreateNewInstance(options);
}
}
您提供了AppDbContext的实现:
you provide an implementation for AppDbContext:
public class AppDbContextFactory : DesignTimeDbContextFactoryBase<AppDbContext>
{
protected override AppDbContext CreateNewInstance(DbContextOptions<AppDbContext> options)
{
return new AppDbContext(options);
}
}
该Add-Migration(或者从技术上讲,是Microsoft.EntityFrameworkCore
that Add-Migration (or maybe technically Microsoft.EntityFrameworkCore.Tools) will detect.
有很多要添加的nuget包:
there were a lot of nuget packages to add:
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.1" />
</ItemGroup>
一旦您克服了错误,我又遇到了一个错误:找不到
,所以我将应用设置 SqlConnection
更改为 default
。
once you get past your error, i got another one: Could not find a connection string named 'default'.
so i changed appsettings SqlConnection
to default
.
这篇关于WPF与网络核心上的实体框架-无法创建和创建AppDbContext类型的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!