Как запустить пакет инструкций SQL с помощью SQLite.NET PCL

в прошлом я избегал ORM и всегда создавал параметризованные запросы и т. д. Это очень много времени и настоящая боль при первой разработке приложения. Недавно я решил еще раз взглянуть на ORM конкретно Sqlite.NET ОРМ.

Я хотел бы использовать функции SQLite ORM, но также иметь возможность запускать пакет собственных команд SQL для предварительного заполнения базы данных.

мы используем dll sqlitenetextensions-MvvmCross для включения один ко многим отношения и т. д., И все это выглядит нормально. Мои проблемы возникают, когда я хочу заполнить базу данных данными конфигурации. Я надеялся просто предоставить файл sql, содержащий серию SQL-операторов, которые он будет запускать один за другим.

Я схватил SQlite.NET код из GITHub и запустите тесты. Затем я расширил класс StringQueryTests, который имеет простую таблицу [Product], чтобы сделать следующее:-

     [Test]
    public void AlanTest()
    {
      StringBuilder sb = new StringBuilder(200);
      sb.Append(" DELETE FROM Product;");
      sb.Append(" INSERT INTO Product VALUES (1,"Name1",1,1);");
      sb.Append(" INSERT INTO Product VALUES (2,"Name2",2,3);");
      db.Execute(sb.ToString());
    }

когда я запускаю это он не выбрасывает ошибка и на самом деле поведение, похоже, заключается в том, что он будет запускать только первую команду. Если я вставлю содержимое sb.ToString () в окне запроса базы данных sqlite будет работать нормально.

это ожидаемое поведение? Если да, то как мне преодолеть это, чтобы я мог использовать такой подход, как выше. Я действительно не хочу создавать объекты для управления всеми инструкциями SQL, если это возможно.

Я вижу, что есть ряд подходов, которые могут быть приняты для преодолейте эту проблему-у кого-нибудь есть работа или предложения, которые, по их мнению, могут решить эту проблему?

С уважением

Алан.

2 ответов


Я только что столкнулся с этой проблемой. Я нашел сообщение в блоге, которое объясняет, почему.

вот что говорит сообщение, если оно пропадет.

весь код [в sqlite-net] правильно проверяет коды результатов и выдает исключения соответственно.

хотя я не разместил здесь весь соответствующий код, я его просмотрел, и реальное происхождение этого поведения находится в другом месте - в родном sqlite3.dll sqlite3_prepare_v2 метод. Вот соответствующая часть документации:

эти процедуры компилируют только первый оператор в zSql, поэтому *pzTail остается указывающим на то, что остается несжатым. Поскольку sqlite-net ничего не делает с несжатым хвостом, фактически выполняется только первый оператор в команде. Остальное молча игнорируется. В большинстве случаев вы не заметите этого при использовании sqlite-net. Вы будете использовать его слой micro ORM или выполнять отдельные операторы. Единственное общее исключение, которое приходит на ум, пытается выполнить сценарии DDL или миграции, которые обычно являются пакетами нескольких операторов.


не можете ли вы сделать:

    [Test]
    public void AlanTest()
    {
        var queries = new List<string> () 
        {
            " DELETE FROM Product",
            " INSERT INTO Product VALUES (1,\"Name1\",1,1)",
            " INSERT INTO Product VALUES (2,\"Name2\",2,3)"
        };

        db.BeginTransaction ();
        queries.ForEach (query => db.Execute (query));
        db.Commit ();
    }

вам действительно не нужна транзакция, просто более быстрое выполнение / откат контрольной точки...