【问题标题】:WPF with entity framework on net core - unable to create and object of type AppDbContext带有网络核心实体框架的 WPF - 无法创建 AppDbContext 类型的对象
【发布时间】:2020-02-10 13:42:29
【问题描述】:

当我使用实体框架时,我有简单的 WPF Net Core 应用程序,我有 DbContext,但是当我添加迁移时,我收到错误:

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

{
  "ConnectionStrings": {
    "SqlConnection": "Server=DESKTOP-K6R1EB3\\tester;Database=test;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

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

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));
        }
    }
}

当然我有简单的数据库模型

namespace WpfApp1
{
    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Surname { get; set; }
    }
}

怎么了?我搜索解决方案,但我什么也没找到。早期我在网络核心和实体框架中编写网络应用程序,我没有任何问题。这是我的第一个 WPF Net Core 应用程序,我的 EF 配置有问题。

【问题讨论】:

    标签: wpf entity-framework .net-core


    【解决方案1】:

    我能够重现您的问题并解决它。

    我以前遇到过这种情况。这篇文章指导我完成了我需要做的事情,非常感谢:https://blog.tonysneed.com/2018/12/20/idesigntimedbcontextfactory-and-dependency-injection-a-love-story/

    来自错误消息中的文章:https://go.microsoft.com/fwlink/?linkid=851728。特别是这部分https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dbcontext-creation#from-a-design-time-factory,我们可以使用一些鸭子类型并提供一个Microsoft.EntityFrameworkCore.Tools 将用来创建迁移的类,实现IDesignTimeDbContextFactory&lt;T&gt;。

    tony sneed 的文章提供了一个通用的抽象实现,然后我们可以非常简单地推导出它。

    这是通用的抽象实现(编辑,抱歉,我刚刚意识到我复制粘贴了我之前遇到此问题时使用的 tony sneed 代码的改编):

    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 提供了一个实现:

    public class AppDbContextFactory : DesignTimeDbContextFactoryBase<AppDbContext>
    {
        protected override AppDbContext CreateNewInstance(DbContextOptions<AppDbContext> options)
        {
            return new AppDbContext(options);
        }
    }
    

    Add-Migration(或者技术上可能是 Microsoft.EntityFrameworkCore.Tools)将检测到。

    有很多 nuget 包要添加:

    <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>
    

    一旦你克服了你的错误,我得到了另一个错误:Could not find a connection string named 'default'. 所以我将 appsettings SqlConnection 更改为 default。

    【讨论】:

      猜你喜欢
      • 2020-05-30
      • 1970-01-01
      • 2019-12-08
      • 2021-05-12
      • 2019-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-09
      相关资源
      最近更新 更多