如何解决无法创建类型为“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_0
1.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 举报,一经查实,本站将立刻删除。