Проблемы с первичным ключом при переносе «устаревших» баз данных SQLite для использования Entity Framework - PullRequest
2 голосов
/ 14 октября 2010

Я недавно начал работу над проектом, который уже работает в течение нескольких лет. Приложение написано на c # с использованием Windows Forms для пользовательского интерфейса и SQLite для базы данных. В настоящее время доступ к базе данных осуществляется через ADO.NET через пространство имен System.Data.SQLite.

Время от времени клиенты получали обновления приложений и баз данных, но не все сразу, поэтому существуют многочисленные, структурно разные версии базы данных. Что еще хуже, клиенты могут добавлять свои собственные поля в таблицы приложения для включения настраиваемых отчетов и т. Д. Таким образом, количество различных баз данных выходит из-под контроля. Когда были внесены улучшения, было добавлено все больше и больше кода "если-то-еще", чтобы приложение работало для всех этих вариантов базы данных.

В дополнение к этому, SQLite имеет раздражающую особенность, заключающуюся в том, что значения в полях могут храниться как любой тип, а не только тип, определенный в операторе create таблицы. Обычно данные импортируются из файлов CSV из Excel, которые имеют неправильные значения даты / времени, которые SQLite успешно импортирует, но в коде мы получаем всевозможные исключения недопустимых типов.

Я хочу положить конец всему этому.

Для очистки базы данных я предлагаю стандартный дизайн базы данных, который не изменится, если мы не выпустим официальное обновление вместе с кодом для автоматической миграции данных.

Я выбрал новейший "ad-hoc" дизайн и, не меняя имен таблиц и полей, сделал его по меньшей мере дружественным к Entity Framework, обеспечив, чтобы первичные ключи были определены для существующих полей и чтобы использовались согласованные типы.

Сейчас я пытаюсь перенести различные устаревшие базы данных по одному. Я использую технику загрузки всех записей в каждой таблице, используя "SELECT * FROM [LEGACY_TABLE];" и создание новых объектов Entity Framework с использованием new EF_Table() { ID = GetValue<long>(dr, "ID"), Description = GetValue<string>(dr, "Description"), };. Я определил GetValue для обработки плохо отформатированных данных и DBNull ссылок и т. Д.

Моя главная проблема сейчас заключается в том, что во многих таблицах есть первичные ключи, определенные как «INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL», что не позволяет Entity Framework назначать текущие значения ключей из устаревшей базы данных.

В процессе миграции мне нужно убедиться, что первичные ключи остаются такими же, так как не определено никаких отношений внешних ключей, а существующие значения первичных ключей хранятся вне базы данных в данных конфигурации приложения.

Я искал решение, но не вижу его. Я бы подумал, что проблема такого рода - миграция и / или очистка существующей базы данных SQLite - была бы решенной проблемой.

Кто-нибудь может указать мне продуктивное направление для решения этой проблемы?

1 Ответ

1 голос
/ 14 октября 2010

Ну, это было довольно просто обойти эту проблему.

Оказывается, что первичные ключи, определенные 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>

Я изменил «Идентичность» на «Нет» следующим образом:

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

Я сделал это со всеми полями автоинкремента, и я мог выполнить миграцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...