c# - 迁移 "Legacy"SQLite 数据库以使用 Entity Framework 时的主键问题

标签 c# .net sql entity-framework sqlite

我最近开始从事一个已经运行多年的项目。该应用程序是用 c# 编写的,使用 Windows 窗体作为 UI 和 SQLite 作为数据库。当前通过 System.Data.SQLite 使用 ADO.NET 访问数据库命名空间。

客户端会不时收到应用程序和数据库更新,但不是一次全部更新,因此存在许多结构不同的数据库版本。更糟糕的是,客户可以将自己的字段添加到应用程序的表中以启用自定义报告等。因此,不同数据库的数量无法控制。在进行功能增强时,会添加越来越多的“if-then-else”代码,以保持应用程序针对所有这些数据库变体运行。

除此之外,SQLite 还有一个烦人的特性,即字段中的值可以存储为任何类型,而不仅仅是表创建语句中定义的类型。从 Excel 中的 CSV 文件导入数据很常见,这些文件具有 SQLite 乐于导入的不正确日期/时间值,但在代码下我们会遇到各种无效类型异常。

我想阻止这一切。

为了清理数据库,我正在发起一个标准的数据库设计,除非我们发布官方更新以及自动迁移数据的代码,否则该设计不会改变。

我采用了最新的“临时”设计,并且在不更改表和字段名称的情况下,通过确保为现有字段定义主键并使用一致的类型,使其至少对 Entity Framework 友好。

我现在正尝试一个接一个地迁移各种遗留数据库。我正在使用一种技术,使用“SELECT * FROM [LEGACY_TABLE];”加载每个表中的所有记录;并使用 new EF_Table() { ID = GetValue<long>(dr, "ID"), Description = GetValue<string>(dr, "Description"), }; 创建新的 Entity Framework 对象.我定义了 GetValue处理转换格式错误的数据和 DBNull引用文献等

我现在的主要问题是许多表的主键定义为“INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL”,这将不允许 Entity Framework 从旧数据库分配当前键值。

在迁移过程中,我需要确保主键保持不变,因为没有定义外键关系,并且现有主键值存储在数据库外部的应用程序配置数据中。

我四处寻找解决方案,但没有找到。我原以为这种问题 - 现有 SQLite 数据库的迁移和/或清理 - 本来可以解决的。

谁能指出我解决这个问题的有效方向?

最佳答案

好吧,解决这个问题非常简单。

事实证明, Entity Framework 在“edmx”文件中定义的主键具有用于自动递增主键的属性 StoreGeneratedPattern="Identity"。通过将值更改为 StoreGeneratedPattern="None", Entity Framework 允许通过代码中的简单赋值来更新主键。

因此,例如,当我有这个表定义时:

CREATE TABLE "FM_Location" (
    [ID] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
    [Location] TEXT
);

然后在“edmx”文件中定义了以下“EntityType”元素:

<EntityType Name="FM_Location">
    <Key>
        <PropertyRef Name="ID" />
    </Key>
    <Property Name="ID" Type="integer" Nullable="false"
            StoreGeneratedPattern="Identity" />
    <Property Name="Location" Type="nvarchar" />
</EntityType>

我像这样将“Identity”更改为“None”:

<EntityType Name="FM_Location">
    <Key>
        <PropertyRef Name="ID" />
    </Key>
    <Property Name="ID" Type="integer" Nullable="false"
            StoreGeneratedPattern="None" />
    <Property Name="Location" Type="nvarchar" />
</EntityType>

我对所有自动递增字段都这样做了,我可以进行迁移。

关于c# - 迁移 "Legacy"SQLite 数据库以使用 Entity Framework 时的主键问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3932097/

相关文章:

c# - 为什么要使用两个IPEndPoint?

c# - 是否有基于 TPL(异步/等待)的套接字抽象?

.net - 在 WPF 中将像素转换为 CM

MySQL 对多个 OR 使用索引,但对 IN 没有索引而且速度慢得多

sql - ORA-00918:列在SELECT中的定义不明确*

c# - .NET - c# - 需要跨分区查询,但禁用了 DocumentDB 数据访问问题

c# - 谷歌地图图像失真(Xamarin)

c# - 如何根据登录成功在新窗口/选项卡或同一窗口/选项卡中打开页面?

.net - 在哪里可以了解 .NET 框架中的权限?

mysql - SQL 仅选择列上具有最大值的行