OrmLite:SQLiteExceptionSQL逻辑错误或“)”附近缺少数据库:语法错误

时间:2015-05-19 07:17:28

标签: c# sqlite servicestack ormlite-servicestack

您好我试图测试我是否删除了父对象,使用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逻辑错误或缺少数据库

near“)”:语法错误    在System.Data.SQLite.SQLite3.Prepare(SQLiteConnection cnn,String strSql,SQLiteStatement previous,UInt32 timeoutMS,ref String strRemain)    在System.Data.SQLite.SQLiteCommand.BuildNextCommand()    在System.Data.SQLite.SQLiteDataReader.NextResult()    在System.Data.SQLite.SQLiteDataReader..ctor(SQLiteCommand cmd,CommandBehavior表现)    在System.Data.SQLite.SQLiteCommand.ExecuteReader(CommandBehavior行为)    在System.Data.SQLite.SQLiteCommand.ExecuteScalar(CommandBehavior行为)    在ServiceStack.OrmLite.OrmLiteReadCommandExtensions.LongScalar(IDbCommand dbCmd)    在ServiceStack.OrmLite.OrmLiteWriteCommandExtensions.Save(IDbCommand dbCmd,T obj)    在ServiceStack.OrmLite.OrmLiteWriteApi。&lt;&gt; c__DisplayClass39'1。b__38(IDbCommand dbCmd)    在ServiceStack.OrmLite.OrmLiteExecFilter.Exec(IDbConnection dbConn,Func`2过滤器)    在Class1.cs的ClassLibrary2.Class1.DeleteById_AlsoDeleteChild_Test()中:第35行

1 个答案:

答案 0 :(得分:1)

此问题是因为Foo没有任何INSERT列,因为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));
}