EF迁移遇到问题的总结记录

在使用 EF 迁移时,会遇到一些问题,本文记录一下作者遇到的错误,及解决方法

4.5
(4)
EF迁移遇到问题的总结记录

错误1

Build failed.

如果 只是单纯提示 Build failed. 则优先检查项目是否可以编译通过,一般都是因为项目无法编译通过导致的。

【范例】

PM> Add-Migration initial
Build started...
Build failed.

错误2

No DbContext was found in assembly ‘MyBlog’. Ensure that you’re using the correct assembly and that the type is neither abstract nor generic.

这是因为,没有找到 DbContext 文件,在 Package Manager Console 的 Default project 必须选中,包含 DbContext 的项目(例如这里必须选中 MyBlog.Model),如果没有选中则发生如下图所示的错误。

EF迁移遇到问题的总结记录

错误3

项目为ASP.NET MVC项目,生成迁移文件时,报告如下错误

Unable to create an object of type ‘MyBlogContext’. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728

>在程序包管理器中调用 Add-Migration 时产生该错误

PM> Add-Migration test
Build started...
Build succeeded.
Unable to create an object of type 'MyBlogContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728

DbContext 代码

public class MyBlogContext : DbContext
{
    public MyBlogContext(DbContextOptions options) : base(options)
    {

    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ArticleLabel>().HasKey(x => new { x.ArticleId, x.LabelId });
    }

    //添加实体
    public DbSet<ArticleLabel> ArticleLabel { get; set; }
    public DbSet<Article> Articles { get; set; }
    public DbSet<User> Users { get; set; }
    public DbSet<Sort> Sorts { get; set; }
    public DbSet<Label> Labels { get; set; }
    public DbSet<Comment> Comments { get; set; }
}

解决办法

在Startup中注入依赖服务,一般这是因为 DbContext 构造函数从外部没有接收到配置(连接字符串、数据库类型等),注入如下服务后,Add-Migration 可以获取 DbContext 的配置信息。

services.AddDbContext<MyBlogContext>(
        options => options.UseSqlite(@"Data Source=C:\Users\mirror\Desktop\GitRepository\MyBlog测试项目\test2\MyBlog\MyBlog\SqliteDB\MyBlogSqlite.db")
        );

也可以使用 DbContext 的无参构造函数,这样配置在DbContext 类内部,也不会出现找不到,连接字符串等配置的问题

【范例】可以参考如下代码:

public class MyBlogContext : DbContext
{
    public MyBlogContext()
    {

    }


    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        string CurrentDbPath = @"C:\Users\mirror\Desktop\GitRepository\MyBlog_Project\MyBlog\MyBlog\SqliteDB\MyBlogSqlite.db";
        optionsBuilder.UseSqlite($"Data Source={CurrentDbPath}");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ArticleLabel>().HasKey(x => new { x.ArticleId, x.LabelId });
    }

    //添加实体
    public DbSet<ArticleLabel> ArticleLabel { get; set; }
    public DbSet<Article> Articles { get; set; }
    public DbSet<User> Users { get; set; }
    public DbSet<Sort> Sorts { get; set; }
    public DbSet<Label> Labels { get; set; }
    public DbSet<Comment> Comments { get; set; }
}





错误4

Format of the initialization string does not conform to specification starting at index 0.

执行 update-database 时发生此错误

PM> update-database
Build started...
Build succeeded.
System.ArgumentException: Format of the initialization string does not conform to specification starting at index 0.
   at System.Data.Common.DbConnectionOptions.GetKeyValuePair(String connectionString, Int32 currentPosition, StringBuilder buffer, Boolean useOdbcRules, String& keyname, String& keyvalue)
   at System.Data.Common.DbConnectionOptions.ParseInternal(Dictionary`2 parsetable, String connectionString, Boolean buildChain, Dictionary`2 synonyms, Boolean firstKey)
   at System.Data.Common.DbConnectionOptions..ctor(String connectionString, Dictionary`2 synonyms, Boolean useOdbcRules)
   at System.Data.Common.DbConnectionStringBuilder.set_ConnectionString(String value)
   at Microsoft.Data.Sqlite.SqliteConnectionStringBuilder..ctor(String connectionString)
   at Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal.SqliteDatabaseCreator.Exists()
   at Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.Exists()
   at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(String targetMigration, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Format of the initialization string does not conform to specification starting at index 0.

出现此问题一般分为两种情况:

1. 数据库连接字符串配置不正确 。

2、配置文件没有正确设置,比如设置配置文件“复制到输出目录”选项配置错误 ,造成程序运行目录下没有配置文件,无法获取读取配置文件数据库连接字符串

错误5

The entity type ‘ArticleLabel’ requires a primary key to be defined. If you intended to use a keyless entity type call ‘HasNoKey()’.

看到上面提示也有知道 ,ArticleLabel 这个实体类的 primary key 没有配置好。

【范例】

PM> Add-Migration initial
Build started...
Build succeeded.
System.InvalidOperationException: The entity type 'ArticleLabel' requires a primary key to be defined. If you intended to use a keyless entity type call 'HasNoKey()'.
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelValidator.ValidateNonNullPrimaryKeys(IModel model, IDiagnosticsLogger`1 logger)
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger)
   at Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger)
   at Microsoft.EntityFrameworkCore.Sqlite.Internal.SqliteModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger)
   at Microsoft.EntityFrameworkCore.Metadata.Conventions.ValidatingConvention.ProcessModelFinalized(IConventionModelBuilder modelBuilder, IConventionContext`1 context)
   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnModelFinalized(IConventionModelBuilder modelBuilder)
   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.OnModelFinalized(IConventionModelBuilder modelBuilder)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.Model.FinalizeModel()
   at Microsoft.EntityFrameworkCore.ModelBuilder.FinalizeModel()
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder)
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, IConventionSetBuilder conventionSetBuilder)
   at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel()
   at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()
   at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder.<>c.<TryAddCoreServices>b__7_3(IServiceProvider p)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
   at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
   at Microsoft.EntityFrameworkCore.DbContext.Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure<System.IServiceProvider>.get_Instance()
   at Microsoft.EntityFrameworkCore.Infrastructure.Internal.InfrastructureExtensions.GetService[TService](IInfrastructure`1 accessor)
   at Microsoft.EntityFrameworkCore.Infrastructure.AccessorExtensions.GetService[TService](IInfrastructure`1 accessor)
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func`1 factory)
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
The entity type 'ArticleLabel' requires a primary key to be defined. If you intended to use a keyless entity type call 'HasNoKey()'.

一般都是主键没有配置好

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<ArticleLabel>()
		.HasKey(x => new { x.ArticleId, x.LabelId });
}

错误6

No database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.OnConfiguring method or by using AddDbContext on the application service provider. If AddDbContext is used, then also ensure that your DbContext type accepts a DbContextOptions<TContext> object in its constructor and passes it to the base constructor for DbContext.

PM> Add-Migration inital 
Build started...
Build succeeded.
System.InvalidOperationException: No database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.OnConfiguring method or by using AddDbContext on the application service provider. If AddDbContext is used, then also ensure that your DbContext type accepts a DbContextOptions<TContext> object in its constructor and passes it to the base constructor for DbContext.
   at Microsoft.EntityFrameworkCore.Internal.DbContextServices.Initialize(IServiceProvider scopedProvider, IDbContextOptions contextOptions, DbContext context)
   at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
   at Microsoft.EntityFrameworkCore.DbContext.Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure<System.IServiceProvider>.get_Instance()
   at Microsoft.EntityFrameworkCore.Infrastructure.Internal.InfrastructureExtensions.GetService[TService](IInfrastructure`1 accessor)
   at Microsoft.EntityFrameworkCore.Infrastructure.AccessorExtensions.GetService[TService](IInfrastructure`1 accessor)
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func`1 factory)
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
No database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.OnConfiguring method or by using AddDbContext on the application service provider. If AddDbContext is used, then also ensure that your DbContext type accepts a DbContextOptions<TContext> object in its constructor and passes it to the base constructor for DbContext.

【范例】 DbContext

public class MyBlogContext : DbContext
{
    public string DbPath { get; set; }
    public MyBlogContext()
    {
        //var folder = Environment.SpecialFolder.LocalApplicationData;
        var path = @"C:\Users\mirror\Desktop\GitRepository\MyBlog测试项目\MyBlog\MyBlog\SqliteDB\";
        DbPath = System.IO.Path.Join(path, "MyBlogSqlite.db");
    }

    // The following configures EF to create a Sqlite database file in the
    // special "local" folder for your platform.
    //protected override void OnConfiguring(DbContextOptionsBuilder options)
    //    => options.UseSqlite($"Data Source={DbPath}");


    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ArticleLabel>().HasKey(x => new { x.ArticleId, x.LabelId });
    }

    //添加实体
    public DbSet<ArticleLabel> ArticleLabel { get; set; }
    public DbSet<Article> Articles { get; set; }
    public DbSet<User> Users { get; set; }
    public DbSet<Sort> Sorts { get; set; }
    public DbSet<Label> Labels { get; set; }
    public DbSet<Comment> Comments { get; set; }
}

解决:

一般都是,DbContext 使用无参构造函数,又没有 OnConfiguring 方法 配置 连接字符串

共计4人评分,平均4.5

到目前为止还没有投票~

很抱歉,这篇文章对您没有用!

让我们改善这篇文章!

告诉我们我们如何改善这篇文章?

文章目录

本文投稿作者:飒飒,如若转载,请注明出处:https://iymark.com/articles/3124.html

(2)
微信公众号
飒飒的头像飒飒普通用户
上一篇 2022年09月22日 20:55
下一篇 2022年09月24日 19:17

你可能感兴趣的文章

发表回复

登录后才能评论
微信小程序
微信公众号