代码之家  ›  专栏  ›  技术社区  ›  Enigmativity

迁移“遗留”SQLite数据库以使用实体框架时的主要关键问题

  •  2
  • Enigmativity  · 技术社区  · 14 年前

    我最近开始做一个已经运行了好几年的项目。应用程序是用c#编写的,UI使用Windows窗体,数据库使用SQLite。当前使用ADO.NET通过 System.Data.SQLite 命名空间。

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

    我想停止这一切。

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

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

    我现在正试图逐个迁移各种遗留数据库。我使用的技术是使用“SELECT*FROM[LEGACY_table];”加载每个表中的所有记录,并使用 new EF_Table() { ID = GetValue<long>(dr, "ID"), Description = GetValue<string>(dr, "Description"), }; . 我已经定义了 GetValue 处理转换格式错误的数据和 DBNull

    我现在的主要问题是,许多表的主键被定义为“INTEGER primary KEY AUTOINCREMENT NOT NULL”,这将不允许实体框架从遗留数据库分配当前的键值。

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

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

    1 回复  |  直到 14 年前
        1
  •  1
  •   Enigmativity    14 年前

    好吧,绕过这个问题很简单。

    原来,由实体框架在“edmx”文件中定义的主键有一个属性 StoreGeneratedPattern="Identity" 用于自动递增主键。通过将值更改为 StoreGeneratedPattern="None" 实体框架允许通过代码中的简单赋值更新主键。

    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>
    

    我把“身份”改成了“无”:

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

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