热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

在EFCore3.0中使用SQLite数据库时遇到Database.MigrateAsync方法调用问题的解决方案

在开发Xamarin.Forms应用程序时,遇到了使用EntityFrameworkCore3.0访问SQLite数据库时`Database.MigrateAsync`方法调用的问题。本文详细探讨了该问题的根源,并提供了一种有效的解决方案,确保数据库迁移能够顺利执行。此外,还介绍了如何配置和优化EFCore以提高应用性能和稳定性。

我正在开发一个Xamarin.Forms应用程序,该应用程序使用通过Entity Framework Core访问的SQLite数据库(版本3,我当前使用的是预发行版,因为我错过了官方3.0的发行版,我会尽快升级)。

每次启动应用程序后,立即实例化ApplicationContext类之后,我都会调用Database.MigrateAsync以确保将数据库升级到该模型的最新版本。我知道我可以通过在应用程序每次启动时不调用MigrateAsync来极大地提高性能,而仅在新版本的第一次运行之后调用它,但这不是重点。

问题是,在我的用户中,只有极少数(约0.5%)MigrateAsync引发类型为

Appetizers

Soups
的异常(通过VS App Center崩溃报告功能进行了报告)。
现在,我知道__EFMigrationHistory是EF Core使用的表,用于跟踪应用的迁移,并且第一次创建数据库文件时应由框架本身创建。

那么,这样的错误怎么可能发生呢?因为,如果该表不存在,则应创建该表,而如果该表存在,则应使用该表来考虑已应用了哪些迁移。也许EF Core尝试创建表,由于某些未知原因而失败,然后尝试抛出此异常读取它?但是什么导致它无法创建表呢?在这种情况下我该怎么办?

由于我目前不跟踪此类信息,因此我目前无法确定是在应用程序的首次运行时(应该不进行迁移时)还是随后引发此异常。另外,我在开发过程中从未遇到过这样的异常。
我可以说,该异常捕获在catch块中,报告给App Center,然后重新抛出,根据App Center的报告,顺便说一句,这应该导致崩溃,而崩溃似乎不会发生。这可能与以下事实有关:异常可能会在异步代码中引发,而该异步代码可能尚未等待或由调用者处理(初始化代码是在实例化ApplicationContext类后由Autofac调用的),但这对我的问题不是必需的。 / p>

这是我称为MigrateAsync的代码:

microsoft.Data.Sqlite.SqliteException: SQLite Error 1: 'no such table: __EFMigrationsHistory'

这是在创建ApplicationContext的单个实例时向Autofac注册的代码:

public class ApplicationContext : DbContext
{
// Other code...
public async Task Initialize()
{
if (IsInitialized) return this;
IsInitialized = true;
try
{
await Database.MigrateAsync();
Analytics.TrackEvent("Migration OK");
}
catch (Exception ex)
{
Crashes.TrackError(ex,new Dictionary { { Globals.CrashProperty.Context.ToString(),"Migration" } });
throw;
}
return this;
}
}

这是VS App Center报告的异常的堆栈跟踪:

public class AppModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
// Other services registrations…
builder.Register(ctx => new ApplicationContext(ctx.Resolve(
new TypedParameter(typeof(string),Globals.DbFileName),new TypedParameter(typeof(FilePathType),FilePathType.AppFolder)).FilePath,ctx.Resolve())).SingleInstance();
base.Load(builder);
}
protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry,IComponentRegistration registration)
{
registration.activated += async (_,args) =>
{
if (args.Instance is ApplicationContext context && !context.IsInitialized)
{
await context.Initialize();
}
};
base.AttachToComponentRegistration(componentRegistry,registration);
}
}
}


我知道这是一个非常老的问题,但是我遇到了同样的问题,并认为值得更新,因为这是我通过google找到的第一个结果。

使用以下命令创建数据库时,会发生此错误:

context.Database.EnsureCreated();

如果最初使用它来创建数据库,则永远不会创建__EFMigrationsHistory表,这将阻止迁移工作。

如果您拥有完整的迁移历史记录,则以下内容可能对您不起作用。 EF将尝试并应用所有迁移,包括那些可能具有表的迁移。无需使用正确的迁移来手动填充__EFMigrationsHistory表以匹配状态-您可能必须参考下面的最终答案。

按照this question的回答,您可以执行以下操作来纠正此问题:

创建__EFMigrationsHistory表后,其余的更新应运行。

CREATE TABLE `__EFMigrationsHistory` ( `MigrationId` nvarchar(150) NOT NULL,`ProductVersion` nvarchar(32) NOT NULL,PRIMARY KEY (`MigrationId`) );

或者,使用Package Manager控制台中的以下命令,生成迁移脚本并手动将其应用于数据库:

Script-Migration

如果需要生成所有脚本,则可以使用以下命令:

Script-Migration -from 0

除了此答案之外,如果您已经有一些由于表和列已存在而无法应用的迁移,则可以执行以下操作:

(警告,这将删除现有数据库及其所有数据-这是最后一个选择-而不是第一个)

if (!context.Database.GetAppliedMigrations().Any())
context.Database.EnsureDeleted()

然后继续进行以下操作:

content.Database.Migrate()

这将确保如果不存在任何迁移,将删除数据库并使用迁移表重新初始化数据库,并应用所有挂起的迁移。


推荐阅读
  • 本文将介绍一种扩展的ASP.NET MVC三层架构框架,并通过使用StructureMap实现依赖注入,以降低代码间的耦合度。该方法不仅能够提高代码的可维护性和可测试性,还能增强系统的灵活性和扩展性。通过具体实践案例,详细阐述了如何在实际开发中有效应用这一技术。 ... [详细]
  • Django框架下的对象关系映射(ORM)详解
    在Django框架中,对象关系映射(ORM)技术是解决面向对象编程与关系型数据库之间不兼容问题的关键工具。通过将数据库表结构映射到Python类,ORM使得开发者能够以面向对象的方式操作数据库,从而简化了数据访问和管理的复杂性。这种技术不仅提高了代码的可读性和可维护性,还增强了应用程序的灵活性和扩展性。 ... [详细]
  • MySQL:不仅仅是数据库那么简单
    MySQL不仅是一款高效、可靠的数据库管理系统,它还具备丰富的功能和扩展性,支持多种存储引擎,适用于各种应用场景。从简单的网站开发到复杂的企业级应用,MySQL都能提供强大的数据管理和优化能力,满足不同用户的需求。其开源特性也促进了社区的活跃发展,为技术进步提供了持续动力。 ... [详细]
  • 深入解析:RKHunter与AIDE在入侵检测中的应用与优势
    本文深入探讨了RKHunter与AIDE在入侵检测领域的应用及其独特优势。通过对比分析,详细阐述了这两种工具在系统完整性验证、恶意软件检测及日志文件监控等方面的技术特点和实际效果,为安全管理人员提供了有效的防护策略建议。 ... [详细]
  • 表面缺陷检测数据集综述及GitHub开源项目推荐
    本文综述了表面缺陷检测领域的数据集,并推荐了多个GitHub上的开源项目。通过对现有文献和数据集的系统整理,为研究人员提供了全面的资源参考,有助于推动该领域的发展和技术进步。 ... [详细]
  • 本文深入探讨了 C# 中 `SqlCommand` 和 `SqlDataAdapter` 的核心差异及其应用场景。`SqlCommand` 主要用于执行单一的 SQL 命令,并通过 `DataReader` 获取结果,具有较高的执行效率,但灵活性较低。相比之下,`SqlDataAdapter` 则适用于复杂的数据操作,通过 `DataSet` 提供了更多的数据处理功能,如数据填充、更新和批量操作,更适合需要频繁数据交互的场景。 ... [详细]
  • 长期以来,关于临时表与表变量的优劣之争一直存在,部分技术社区甚至认为表变量几乎毫无用武之地,如缺乏统计信息、不支持事务处理等。然而,实际情况并非如此绝对。本文将从多个角度对比分析临时表与表变量,探讨它们在不同场景下的应用优势及其潜在局限性,帮助开发者更好地选择合适的数据结构。 ... [详细]
  • MySQL 8.0 中的二进制日志格式详细解析及其官方文档参考。本文介绍了MySQL服务器如何使用不同的日志记录格式来记录二进制日志,包括早期版本中基于SQL语句的复制机制(即基于语句的日志记录)。此外,还探讨了其他日志记录方式,如基于行的日志记录和混合日志记录模式,并提供了配置和管理这些日志格式的最佳实践。 ... [详细]
  • 题目描述:小K不幸被LL邪教洗脑,洗脑程度之深使他决定彻底脱离这个邪教。在最终离开前,他计划再进行一次亚瑟王游戏。作为最后一战,他希望这次游戏能够尽善尽美。众所周知,亚瑟王游戏的结果很大程度上取决于运气,但通过合理的策略和算法优化,可以提高获胜的概率。本文将详细解析洛谷P3239 [HNOI2015] 亚瑟王问题,并提供具体的算法实现方法,帮助读者更好地理解和应用相关技术。 ... [详细]
  • MySQL 数据操作:增、删、查、改全面解析
    MySQL 数据操作:增、删、查、改全面解析 ... [详细]
  • Mongoose E11000 错误:集合中出现重复键问题分析与解决 ... [详细]
  • 在单个图表中实现饼图与条形图的精准对齐 ... [详细]
  • 探讨 jBPM 数据库表结构设计的精要与实践
    探讨 jBPM 数据库表结构设计的精要与实践 ... [详细]
  • 本文深入分析了Django框架中模型应用与非模型应用的区别与应用场景,详细对比了两者在数据处理、性能表现及开发灵活性等方面的特点。同时,文章还介绍了如何在视图函数中有效利用这些特性,结合PostgreSQL、MySQL、SQLite3和Oracle等不同数据库的配置与使用方法,为开发者提供了全面的参考指南。 ... [详细]
  • 程序连接MySQL数据库的多种方法详解 ... [详细]
author-avatar
A_2na轻奢主义总店访烟
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有