560 字
3 分钟
EF Core单独分层无法迁移
EF Core单独分层无法迁移
在开发个人博客项目的时候,我把EF Core单独放到了一层,也就是单独放在了xxx.Blog.EntityFrameworkCore这个类库里面。配置好Context文件后,我开始执行迁移命令
dotnet ef migrations add init
但发现抛出了异常
Unable to create a 'DbContext' of type ''. The exception 'Unable to resolve service for type 'Microsoft.EntityFrameworkCore.DbContextOptions`1[BlogDbContext]' while attempting to activate 'BlogDbContext'.' was thrown while attempting to create an instance. For the different patterns supported at design time, see <https://go.microsoft.com/fwlink/?linkid=851728>
翻译为中文就是:
无法创建类型为"的" DbContext "。异常“无法解析服务类型”Microsoft.EntityFrameworkCore。当试图激活'BlogDbContext'时,DbContextOptions ' 1[BlogDbContext]'。在尝试创建实例时抛出。有关设计时支持的不同模式,请参阅https://go.microsoft.com/fwlink/?linkid=851728
我查看了这篇文档 ,得知执行迁移命令的时候要求必须创建DbContext实例。
如果你的DbContext是在WebApi,那么你可以通过容器来创建DbContext。但是我们现在是把EF Core单独放一层,这个时候最好的方式就是用第二种方式design-time factory,也就是通过IDesignTimeDbContextFactory接口来创建DbContext。如果在与派生 DbContext
接口相同的项目或应用程序的启动项目中找到实现此接口的类,则这些工具将绕过创建 DbContext 的其他方式,而是使用design-time factory来创建。
代码如下:
public class BlogDesignTimeDbContextFactory : IDesignTimeDbContextFactory<BlogDbContext>{ public BlogDbContext CreateDbContext(string[] args) { DbContextOptionsBuilder<BlogDbContext> builder = new(); var configuration=new ConfigurationBuilder().AddJsonFile("appsettings.json").Build(); var connStr=configuration.GetConnectionString("BlogDataConnect"); throw new ArgumentNullException("没有找到连接字符串"); builder.UseSqlServer(connStr); return new BlogDbContext(builder.Options, null); }}
这上面有两个注意的点:
- configuration是我用了
Microsoft.Extensions.Configuration
这个包,通过指定配置文件并且把数据库的连接字符串读取出来。 return new BlogDbContext(builder.Options, null);
这里为什么多了个null入参呢?因为我在BlogContext从构造函数中注入了IHttpContextAccessor
。之所以注入这个是为了使用审计属性。当然这里我建议是用autofac的属性注入,但是因为我这里没有用,所以就先这样了。
public BlogDbContext(DbContextOptions<BlogDbContext> options, IHttpContextAccessor httpContextAccessor) : base(options){ _httpContextAccessor = httpContextAccessor;}
还有第三种方式,但是我不推荐,第三种就是使用迁移命令的时候使用—startup-project来指定启动项目。
参考文档:
EF Core单独分层无法迁移
https://www.tyblog.site/posts/dotnet/efcore-designtime/