Reputation: 2798
Hi i'm trying to test out if I delete a parent object, the child will automatically be deleted too using OrmLite and the in-memory database Sqlite
this is my test code but it throws me System.Data.SQLite.SQLiteExceptionSQL logic error or missing database near ")": syntax error at the db.Save() line.
What might be wrong?
[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 logic error or missing database
near ")": syntax error at System.Data.SQLite.SQLite3.Prepare(SQLiteConnection cnn, String strSql, SQLiteStatement previous, UInt32 timeoutMS, ref String strRemain) at System.Data.SQLite.SQLiteCommand.BuildNextCommand() at System.Data.SQLite.SQLiteDataReader.NextResult() at System.Data.SQLite.SQLiteDataReader..ctor(SQLiteCommand cmd, CommandBehavior behave) at System.Data.SQLite.SQLiteCommand.ExecuteReader(CommandBehavior behavior) at System.Data.SQLite.SQLiteCommand.ExecuteScalar(CommandBehavior behavior) at ServiceStack.OrmLite.OrmLiteReadCommandExtensions.LongScalar(IDbCommand dbCmd) at ServiceStack.OrmLite.OrmLiteWriteCommandExtensions.Save(IDbCommand dbCmd, T obj) at ServiceStack.OrmLite.OrmLiteWriteApi.<>c__DisplayClass39' 1. b__38(IDbCommand dbCmd) at ServiceStack.OrmLite.OrmLiteExecFilter.Exec(IDbConnection dbConn, Func`2 filter) at ClassLibrary2.Class1.DeleteById_AlsoDeleteChild_Test() in Class1.cs: line 35
Upvotes: 1
Views: 2443
Reputation: 143284
This issue is because you Foo
doesn't have any columns to INSERT since Id
is a autoincrementing primary key and Bar
is a [Reference]
property so no columns are saved so the INSERT SQL ends up looking like:
INSERT INTO "Foo" () VALUES ();
This would work if you Foo
had a column, e.g:
public class Foo : IHasIntId
{
[AutoIncrement]
public int Id { get; set; }
[Reference]
public Bar Bar { get; set; }
public string Name { get; set; }
}
Note Foreign key support is not enabled in SQLite by default. You need to enable it manually each time you connect to the database using the pragma:
PRAGMA foreign_keys = ON
So a working example would look like:
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));
}
Upvotes: 1