微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

无法创建类型为“ApplicationDbContext”的对象 EF 核心 5.0

如何解决无法创建类型为“ApplicationDbContext”的对象 EF 核心 5.0

我使用 CleanArchitecture 解决方案。我有 ApplicationDbContext 和 UnitOfWork 所在的数据层:

namespace Portal.Data.MyDbContexts
{
    internal class ApplicationDbContext : DbContext
    {

        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
        {
            Database.EnsureCreated();
        }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.ApplyConfigurationsFromAssembly(typeof(BaseEntity).Assembly);
        }


        // **********
        public DbSet<WebsiteMonitoredCategory> WebsiteMonitoredCategories { get; set; }
        // **********


        
    }

工作单元:

public abstract class BaseUnitOfWork : object,IBaseUnitOfWork
    {
        //public UnitOfWork() : base()
        //{
        //}

        public BaseUnitOfWork(Options options) : base()
        {
            Options = options;
        }

        // **********
        protected Options Options { get; set; }
        // **********

        // **********
        // **********
        // **********
        private ApplicationDbContext _databaseContext;
        // **********

        // **********
        /// <summary>
        /// Lazy Loading = Lazy Initialization
        /// </summary>
        internal ApplicationDbContext DatabaseContext
        {
            get
            {
                if (_databaseContext == null)
                {
                    var optionsBuilder =
                        new DbContextOptionsBuilder<ApplicationDbContext>();

                    switch (Options.Provider)
                    {
                        case Provider.sqlServer:
                            {
                                optionsBuilder.UsesqlServer
                                    (connectionString: Options.ConnectionString);

                                break;
                            }

                        case Provider.MysqL:
                            {
                                //optionsBuilder.UseMysqL
                                //  (connectionString: Options.ConnectionString);

                                break;
                            }

                        case Provider.Oracle:
                            {
                                //optionsBuilder.USEOracle
                                //  (connectionString: Options.ConnectionString);

                                break;
                            }

                        case Provider.Postgresql:
                            {
                                //optionsBuilder.UsePostgresql
                                //  (connectionString: Options.ConnectionString);

                                break;
                            }

                        case Provider.InMemory:
                            {
                                optionsBuilder.UseInMemoryDatabase(databaseName: "Temp");

                                break;
                            }

                        default:
                            {
                                break;
                            }
                    }

                    _databaseContext =
                        new ApplicationDbContext(options: optionsBuilder.Options);
                }

                return _databaseContext;
            }
        }

而且我也有 IoC 层用于对表示层的依赖注入:

public class DependencyContainer
    {
        public static void RegisterServices(IServiceCollection services,IConfiguration configuration)
        {

            
            //DataLayer
            services.AddTransient<IUnitOfWork,UnitOfWork>(_ =>
            {
                Options options =
                    new Options
                    {
                        Provider =
                            (Provider)System.Convert.ToInt32(configuration.GetSection(key: "DatabaseProvider").Value),ConnectionString =
                            configuration.GetSection(key: "ConnectionStrings").GetSection(key: "MyConnectionString").Value,};

                return new UnitOfWork(options: options);
            });


        }
    }

最后我有一个 Windows 窗体应用程序 Net 5.0(所有项目都是 Net5.0)

namespace Portal.Desktop
{
    public static class Program
    {
        private static IConfiguration Configuration { get; set; }
        public static IServiceProvider ServiceProvider { get; set; }
        /// <summary>
        ///  The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            var services = ConfigureServices();

            var builder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json",optional: true,reloadOnChange: true);
            Configuration = builder.Build();

            
        

            Application.SetHighDpiMode(HighDpiMode.SystemAware);
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
            RegisterServices(services,Configuration);
        }

        public static void RegisterServices(IServiceCollection services,IConfiguration configuration)
        {
            DependencyContainer.RegisterServices(services,configuration);
        }

        public static IServiceCollection ConfigureServices()
        {
            var services = new ServiceCollection();
            //services.AddTransient<IUnitOfWork,UnitOfWork>(_ =>
            //{
            //  Options options =
            //      new Options
            //      {
            //          Provider =
            //              (Provider)System.Convert.ToInt32(Configuration.GetSection(key: "DatabaseProvider").Value),//          //using Microsoft.EntityFrameworkCore;
            //          //ConnectionString =
            //          //  Configuration.GetConnectionString().GetSection(key: "MyConnectionString").Value,//          ConnectionString =
            //              Configuration.GetSection(key: "ConnectionStrings").GetSection(key: "MyConnectionString").Value,//      };

            //  return new Portal.Data.UoW.UnitOfWork(options: options);
            //});


            ServiceProvider = services.BuildServiceProvider();

            return services;
        }
    }
}

我使用 Ef core 5.0 ,windows 窗体设置为启动项目,包管理器控制台设置为 Protal.Data(dbcontext 和 unitofwork 在那里) 但是当我在 PMC 中运行 Add-Migration inti 时出现错误

无法创建类型为“ApplicationDbContext”的对象。为了 设计时支持的不同模式,请参阅 https://go.microsoft.com/fwlink/?linkid=851728

在数据层安装这个包:

<ItemGroup>
    <packagereference Include="Microsoft.EntityFrameworkCore" Version="5.0.7" />
    <packagereference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.7">
        <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </packagereference>
    <packagereference Include="Microsoft.EntityFrameworkCore.InMemory" Version="5.0.7" />
    <packagereference Include="Microsoft.EntityFrameworkCore.sqlServer" Version="5.0.7" />
    <packagereference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.7">
        <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </packagereference>
  </ItemGroup>

我不知道为什么,让我知道错误

-----更新----

我遵循 https://go.microsoft.com/fwlink/?linkid=851728 并将 ApplicationDbContextFactory.cs 添加到 Portal.Desktop(Windows 窗体 Net5.0)项目:

namespace Portal.Desktop
{
    public class ApplicationDbContextFactory:IDesignTimeDbContextFactory<ApplicationDbContext>
    {
        public ApplicationDbContext CreateDbContext(string[] args)
        {
            var connectionString = Program.Configuration.GetSection(key: "ConnectionStrings").GetSection(key: "MyConnectionString").Value;
            var provider = Program.Configuration.GetSection(key: "DatabaseProvider").Value;
            var optionsBuilder =
                new DbContextOptionsBuilder<ApplicationDbContext>();
            var options =
                new Options
                {
                    Provider =
                        (Provider)System.Convert.ToInt32(provider),//using Microsoft.EntityFrameworkCore;
                    //ConnectionString =
                    //  Configuration.GetConnectionString().GetSection(key: "MyConnectionString").Value,ConnectionString = connectionString,};
            switch (options.Provider)
            {
                case Provider.sqlServer:
                {
                    optionsBuilder.UsesqlServer
                        (connectionString: options.ConnectionString);

                    break;
                }

                case Provider.MysqL:
                {
                    //optionsBuilder.UseMysqL
                    //  (connectionString: Options.ConnectionString);

                    break;
                }

                case Provider.Oracle:
                {
                    //optionsBuilder.USEOracle
                    //  (connectionString: Options.ConnectionString);

                    break;
                }

                case Provider.Postgresql:
                {
                    //optionsBuilder.UsePostgresql
                    //  (connectionString: Options.ConnectionString);

                    break;
                }

                case Provider.InMemory:
                {
                    optionsBuilder.UseInMemoryDatabase(databaseName: "Temp");

                    break;
                }

                default:
                {
                    break;
                }
            }

            return 
                new ApplicationDbContext(options: optionsBuilder.Options);
        }
    }
}

当我想添加迁移 ef core throw 异常已被调用的目标抛出。 异常:

System.Reflection.TargetInvocationException:已抛出异常 通过调用的目标。 ---> System.NullReferenceException: 你调用的对象是空的。在 Portal.Desktop.ApplicationDbContextFactory.CreateDbContext(String[] args) 在 C:\Users\Arman Es\source\repos\Spider\Portal.Desktop\ApplicationDbContextFactory.cs:line 20 --- 内部异常堆栈跟踪结束 --- 在 System.RuntimeMethodHandle.InvokeMethod(Object target,Object[] 参数、签名 sig、布尔构造函数、布尔 wrapExceptions) 在 System.Reflection.RuntimeMethodInfo.Invoke(Object obj,BindingFlags invokeAttr、Binder 绑定器、Object[] 参数、CultureInfo 文化)
在 System.Reflection.MethodBase.Invoke(Object obj,Object[] 参数)在 Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContextFromFactory(类型 工厂,类型 contextType) 在 Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.c__displayClass13_2.b__9() 在 Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func1 factory) at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType) at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name,String outputDir,String contextType,String namespace) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name,String namespace) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__displayClass0_0.<.ctor>b__0() at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__displayClass3_01.b__0() 在 Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action) 调用的目标已抛出异常。

解决方法

最后,我在这篇文章中找到了答案https://snede.net/you-dont-need-a-idesigntimedbcontextfactory/

在 Portal.Data 项目中创建 ApplicationDbContextFactory

using System.IO;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;
using Portal.Domain.Tools;
using Portal.Domain.Tools.Enums;

namespace Portal.Data.MyDbContexts
{
    public class ApplicationDbContextFactory:IDesignTimeDbContextFactory<ApplicationDbContext>
    {
        private IConfiguration Configuration { get; set; }

        public ApplicationDbContext CreateDbContext(string[] args)
        {

            var builder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json");
            Configuration = builder.Build();

            var optionsBuilder =
                new DbContextOptionsBuilder<ApplicationDbContext>();
            var options =
                new Options
                {
                    Provider =
                        (Provider)System.Convert.ToInt32(Configuration.GetSection(key: "DatabaseProvider").Value),ConnectionString = Configuration.GetSection(key: "ConnectionStrings").GetSection(key: "MyConnectionString").Value
                };

            switch (options.Provider)
            {
                case Provider.SqlServer:
                {
                    optionsBuilder.UseSqlServer
                        (connectionString: options.ConnectionString);

                    break;
                }

                case Provider.MySql:
                {
                    //optionsBuilder.UseMySql
                    //  (connectionString: Options.ConnectionString);

                    break;
                }

                case Provider.Oracle:
                {
                    //optionsBuilder.UseOracle
                    //  (connectionString: Options.ConnectionString);

                    break;
                }

                case Provider.PostgreSQL:
                {
                    //optionsBuilder.UsePostgreSQL
                    //  (connectionString: Options.ConnectionString);

                    break;
                }

                case Provider.InMemory:
                {
                    optionsBuilder.UseInMemoryDatabase(databaseName: "Temp");

                    break;
                }

                default:
                {
                    break;
                }
            }

            return 
                new ApplicationDbContext(options: optionsBuilder.Options);
        }
    }
}

appsettings.json 仍在 Portal.Desktop 项目中:

namespace Portal.Desktop
{
    public static class Program
    {
        public  static IConfiguration Configuration { get; set; }
        public static IServiceProvider ServiceProvider { get; set; }
        /// <summary>
        ///  The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            var services = ConfigureServices();

            RegisterServices(services,Configuration);


            Application.SetHighDpiMode(HighDpiMode.SystemAware);
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
            
        }

        public static void RegisterServices(IServiceCollection services,IConfiguration configuration)
        {
            DependencyContainer.RegisterServices(services,configuration);
        }

        public static IServiceCollection ConfigureServices()
        {
            var services = new ServiceCollection();
            

            ServiceProvider = services.BuildServiceProvider();

            return services;
        }
    }
}

最后IoC项目是:

namespace Portal.IoC
{
    public class DependencyContainer
    {
        public static void RegisterServices(IServiceCollection services,IConfiguration configuration)
        {

            //DataLayer
            services.AddTransient<IUnitOfWork,UnitOfWork>(_ =>
            {
                var options =
                    new Options
                    {
                        Provider =
                            (Provider)System.Convert.ToInt32(configuration.GetSection(key: "DatabaseProvider").Value),ConnectionString =
                            configuration.GetSection(key: "ConnectionStrings").GetSection(key: "MyConnectionString").Value,};

                return new UnitOfWork(options: options);
            });

        


        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。