sqllite: SQLiteExceptionSQL逻辑错误或丢失数据库附近")":语法错误

本文关键字:quot 错误 语法 SQLiteExceptionSQL sqllite 数据库 | 更新日期: 2023-09-27 17:49:36

嗨,我想测试一下,如果我删除父对象,子对象也会自动删除使用OrmLite和内存数据库Sqlite

这是我的测试代码,但它抛出我System.Data.SQLite.SQLiteExceptionSQL逻辑错误或丢失数据库附近")": db.Save()行语法错误。

怎么了?

[Fact]
    public void DeleteById_AlsoDeleteChild_Test()
    {
        var _dbFactory = new OrmLiteConnectionFactory(":memory:", SqliteDialect.Provider);
        using (var db = _dbFactory.OpenDbConnection())
        {
            // arrange
            db.CreateTableIfNotExists<Foo>();
            db.CreateTableIfNotExists<Bar>();
            var foo = new Foo
            {
                Bar = new Bar
                {
                    Name = "Hello"
                }
            };

            db.Save(foo);
            db.SaveReferences(foo, foo.Bar);

            var saved = db.Select<Foo>();

            // act
            db.DeleteById<Foo>(saved.First().Id);
            // assert
            Assert.False(db.Exists<Bar>(c => c.FooId == saved.First().Id));
        }

    }
    public class Foo : IHasIntId
    {
        [AutoIncrement]
        public int Id { get; set; }
        [Reference]
        public Bar Bar { get; set; }
    }
    public class Bar : IHasIntId
    {
        [AutoIncrement]
        public int Id { get; set; }
        [ForeignKey(typeof(Foo), OnDelete = "CASCADE")]
        public int FooId { get; set; }
        public string Name { get; set; }
    }

System.Data.SQLite。SQLiteExceptionSQL逻辑错误或缺少数据库

")附近:语法错误在System.Data.SQLite.SQLite3。准备(SQLiteConnection cnn, String strSql, sqlitestatstatement先前,UInt32 timeoutMS, ref String strRemain)在System.Data.SQLite.SQLiteCommand.BuildNextCommand ()在System.Data.SQLite.SQLiteDataReader.NextResult ()在System.Data.SQLite.SQLiteDataReader . .(SQLiteCommand cmd, CommandBehavior behavior)在System.Data.SQLite.SQLiteCommand。ExecuteReader (CommandBehavior行为)在System.Data.SQLite.SQLiteCommand。ExecuteScalar (CommandBehavior行为)在ServiceStack.OrmLite.OrmLiteReadCommandExtensions。LongScalar (IDbCommand dbCmd)在ServiceStack.OrmLite.OrmLiteWriteCommandExtensions。保存(IDbCommand dbCmd, T obj)在ServiceStack.OrmLite.OrmLiteWriteApi.<>c__DisplayClass39' 1。b__38 (IDbCommand dbCmd)在ServiceStack.OrmLite.OrmLiteExecFilter。执行(IDbConnection dbConn, Func ' 2 filter)at ClassLibrary2.Class1.DeleteById_AlsoDeleteChild_Test() in Class1.cs: line 35

sqllite: SQLiteExceptionSQL逻辑错误或丢失数据库附近")":语法错误

这个问题是因为你的Foo没有任何列插入,因为Id是一个自动递增的主键,Bar是一个[Reference]属性,所以没有列被保存,所以INSERT SQL最终看起来像:

INSERT INTO "Foo" () VALUES (); 

如果你的Foo有一个列,这将工作,例如:

public class Foo : IHasIntId
{
    [AutoIncrement]
    public int Id { get; set; }
    [Reference]
    public Bar Bar { get; set; }
    public string Name { get; set; }
}

注意SQLite默认不支持外键。您需要在每次使用pragma:

连接到数据库时手动启用它。
PRAGMA foreign_keys = ON

所以一个工作的例子看起来像:

using (var db = OpenDbConnection())
{
    db.DropAndCreateTable<Foo>();
    db.DropAndCreateTable<Bar>();
    db.ExecuteNonQuery("PRAGMA foreign_keys = ON");
    var foo = new Foo
    {
        Bar = new Bar
        {
            Name = "Hello"
        }
    };
    db.Save(foo);
    db.SaveReferences(foo, foo.Bar);
    var saved = db.Select<Foo>();
    db.DeleteById<Foo>(saved.First().Id);
    Assert.False(db.Exists<Bar>(c => c.FooId == saved.First().Id));
}