My problem was similar and my search led here. Trying to write a unit test to test my service, I was getting the same "Transaction is not associated with the command's connection" exception. The difference in my situation is that the only transaction I was using (in the service I was testing) WAS correctly disposing of it's connection, so I didn't think this applied.
(I am using ServiceStack v3.9.71.)
My test code (which failed) looked like this:
[Test]
public void Test_Service_Delete() {
var DatabaseFactory = new OrmLiteConnectionFactory(":memory:", false, SqliteDialect.Provider, true);
using (var db = DatabaseFactory.OpenDbConnection()) {
var parentId = db.InsertParam(new ParentObject { name = "Bob" }, true);
db.Insert(new ChildObject { ParentId = parentId, name = "Sam" });
var service = Container.Resolve<TestService>();
var response = service.Delete(new DeleteRequestObject(parentId));
Assert.That(db.Select<ParentObject>(parentId), Has.Count.EqualTo(0));
Assert.That(db.Select<ChildObject>("ParentId = {0}", parentId), Has.Count.EqualTo(0));
}
}
My TestService.Delete method had a transaction in it (because it deletes the object and any associated child objects), but it was wrapped in a using block like so:
using (var db = DatabaseFactory.OpenDbConnection()) {
using (var transaction = db.BeginTransaction(IsolationLevel.ReadCommitted)) {
// do stuff here
}
}
Still, the "Transaction is not associated with the command's connection" exception was thrown on the first line after the call to service.Delete.
My first attempt to solve it (which did not work) was this:
[Test]
public void Test_Service_Delete() {
var DatabaseFactory = new OrmLiteConnectionFactory(":memory:", false, SqliteDialect.Provider, true);
int parentId;
using (var db = DatabaseFactory.OpenDbConnection()) {
parentId = db.InsertParam(new ParentObject { name = "Bob" }, true);
db.Insert(new ChildObject { ParentId = parentId, name = "Sam" });
}
var service = Container.Resolve<TestService>();
var response = service.Delete(new DeleteRequestObject(parentId));
using (var db = DatabaseFactory.OpenDbConnection()) {
Assert.That(db.Select<ParentObject>(parentId), Has.Count.EqualTo(0));
Assert.That(db.Select<ChildObject>("ParentId = {0}", parentId), Has.Count.EqualTo(0));
}
}
What eventually worked was wrapping the db calls after the service call in a transaction.
[Test]
public void Test_Service_Delete() {
var DatabaseFactory = new OrmLiteConnectionFactory(":memory:", false, SqliteDialect.Provider, true);
int parentId;
using (var db = DatabaseFactory.OpenDbConnection()) {
parentId = db.InsertParam(new ParentObject { name = "Bob" }, true);
db.Insert(new ChildObject { ParentId = parentId, name = "Sam" });
}
var service = Container.Resolve<TestService>();
var response = service.Delete(new DeleteRequestObject(parentId));
using (var db = DatabaseFactory.OpenDbConnection()) {
using (var transaction = db.OpenTransaction()) {
Assert.That(db.Select<ParentObject>(parentId), Has.Count.EqualTo(0));
Assert.That(db.Select<ChildObject>("ParentId = {0}", parentId), Has.Count.EqualTo(0));
}
}
}
I'm still fuzzy on WHY this workaround worked, but I figured I'd document it for anyone else running into this.