UWP: развертывание проекта, использующего SQLite и Dapper

Чтобы иметь возможность использовать SQLite в своем проекте UWP, я добавил пакеты Nuget System.Data.SQLite.Core 1.0.111 и Dapper 1.60.6. Он отлично строится и работает. Однако, когда я попытался развернуть этот проект в магазине, я получаю следующие ошибки:

Тест функций безопасности Windows

File C:\myApp\sni.dll has failed the AppContainerCheck check.
File C:\myApp\SQLite.Interop.dll has failed the AppContainerCheck check.

Поддерживаемый тест API

API CryptDuplicateKey in advapi32.dll is not supported for this application type. SQLite.Interop.dll calls this API.
API AreFileApisANSI in kernel32.dll is not supported for this application type. SQLite.Interop.dll calls this API.
...

Я установил флажок «Скомпилировать с собственным набором инструментов» и построил его на конфигурации выпуска, как это предлагается в комплекте сертификации приложений для Windows и другом ответе stackoverflow, но проблема не устранена.

Также в результатах тестирования комплекта сертификации приложений для Windows говорится:

"Apply the required linker options - SAFESEH, DYNAMICBASE, NXCOMPAT, and APPCONTAINER - when you link the app."

Я использую VS 2019, и, учитывая, что этот проект написан на С# (не С++), я не уверен, что параметры компоновщика даже применимы для моего случая.

Еще одна странность заключается в том, что, в отличие от пакетов x86 и x64, нет проблем с развертыванием пакета arm.

Можно ли решить эту проблему, или я должен вообще прекратить использовать эти пакеты nuget.

Вы столкнулись с этими ошибками в вашем локальном WACK?

Xie Steven 29.07.2019 08:37

Да. На самом деле вторая часть, поддерживаемый тест API, я думаю, появляется только в локальном WACK, хотя не уверен.

t.m. 29.07.2019 15:25

К сожалению, онлайн WACK тоже не пропускает пакеты. Он выдает первую ошибку, как это делает WACK, но вторая ошибка на этот раз не такая толстая.

t.m. 05.08.2019 18:37

он много жалуется на sni.dll

t.m. 05.08.2019 18:37

Библиотеки Dapper и SQLite в Nuget кажутся довольно современными. Фильтрует ли Nuget Manager пакеты для UWP? Я думал, что мы можем просто использовать пакеты, которые мы видим в диспетчере пакетов nuget.

t.m. 05.08.2019 18:39

Я хочу знать, следуете ли вы этому официальному документу Использование базы данных SQLite в приложении UWP, чтобы использовать базу данных sqlite в своем приложении uwp.

Xie Steven 06.08.2019 07:32

Я не использовал пакеты nuget на указанной странице. Я использовал System.Data.SQLite.Core от команды разработчиков SQLite и Dapper, потому что с ними мне было удобнее. Я думаю, мне нужно переключиться на те, что по этой ссылке. Спасибо за вашу помощь.

t.m. 06.08.2019 20:46

Верно. Вы должны следовать официальному документу.

Xie Steven 07.08.2019 04:07
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
8
542
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Кажется, что это пока невозможно. Итак, позвольте мне написать другие возможные решения и мой опыт работы с ними.

1 - Использование пакета Microsoft.Data.SQLite

Как предложил Ксавьер Се в разделе комментариев, вы можете использовать это руководство в MSDN. Это своего рода ванильная библиотека для использования SQLite в приложении UWP.

Я не предпочел это по нескольким причинам. На мой взгляд, это многословно по синтаксису и не так уж тривиально для начала. Вы должны быть осторожны с версиями пакетов, которые вы устанавливаете. Что еще более важно, в моем случае вам нужно изменить свои функции чтения и обновления для класса по мере изменения полей этого класса. Таким образом, его сложнее поддерживать, чем при использовании библиотек более высокого уровня, таких как Dapper.

2 - Используйте Entity Framework

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

3 - Используйте метод, отличный от SQLite, для хранения данных

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

Я использовал Пакет Newtonsoft Nuget для сериализации и десериализации классов и использовал Класс ApplicationData для хранения данных. Я думаю, что оба они очень просты в использовании и хорошо документированы с четкими примерами.

Вот некоторые части кода из того, что я сделал:

    const string myDataFilename= "myData.json";
    const string backupFolderPath = "ms-appx:///DataModel/";

    async Task LoadData()
    {
        string json = await StorageApi.ReadFromFile(myDataFilename, backupFolderPath + myClassFilename);
        try
        {
            myList = JsonConvert.DeserializeObject<List<myClass>>(json);
        }
        catch
        {
            // maybe do some reset logic here
            await StorageApi.CopyFile(backupFolderPath + myDataFilename, myDataFilename);
            await LoadData();
        }
    }
    
    async public void saveData()
    {
        string json = JsonConvert.SerializeObject(myList);
        await StorageApi.WriteToFile(myDataFilename, json);
    }

И я написал класс-оболочка для использования класса ApplicationData На случай, если ссылки не работают, вот код из него:

    public static async Task WriteToFile(string relativePath, string data)
    {
        StorageFile sampleFile = await localFolder.CreateFileAsync(relativePath,
            CreationCollisionOption.ReplaceExisting);
        await FileIO.WriteTextAsync(sampleFile, data);
    }

    // Read data from a file
    public static async Task<string> ReadFromFile(string relativePath, string backupPath = "")
    {
        try
        {
            StorageFile sampleFile = await localFolder.GetFileAsync(relativePath);
            return await FileIO.ReadTextAsync(sampleFile);
        }
        catch (FileNotFoundException e)
        {
            Debug.WriteLine( "Relative path: {0}, backupPath: {1}, Error str: {2}", relativePath, backupPath, e.Message);

            if (backupPath == "")
                return "";
            else
            {
                await CopyFile(backupPath, relativePath);
                return await ReadFromFile(relativePath);
            }
        }
        catch (IOException e)
        {
            Debug.WriteLine(e.Message);
        }

        return "";
    }

    public static async Task CopyFile(string src, string relativeDst)
    {
        try
        {
            StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(
                new Uri(src));
            await file.CopyAsync(localFolder, relativeDst, NameCollisionOption.ReplaceExisting);
        }
        catch (FileNotFoundException e)
        {
            Debug.WriteLine(e.Message);
        }
        catch (IOException e)
        {
            Debug.WriteLine(e.Message);
        }
    }

Примечание. Я выберу этот ответ как принятый на данный момент. Если появится лучший ответ, который решает точную проблему, я приму его вместо этого.

Другие вопросы по теме