Reset of multiple different DBs from same Checkpoint is not supported - DeleteSql is cached on initial call to Reset
tafs7 opened this issue · comments
I may have just stepped into a (smallish) landmine. I have an application that relies on 2 databases (multi-tenancy): one for the central config and another for a tenant.
During my integration test fixture setup, I was trying to figure out why I was getting odd SqlExceptions when I called the Checkpoint.Reset(connString)
twice but using different connection strings, telling me it couldn't find the tables to be deleted in my existing schema.
Turns out the DeleteSql string is stored/cached in the instance of Checkpoint
once you call Reset(string)
, so if you have multiple different DBs to reset, you basically need separate instances of Checkpoint
. This is not as intuitive to find out given that the Reset(string)
API expects a connection string. My assumption was that since I am passing in a connection, it will analyze and rebuild the DeleteSql statement upon the call to Reset()
. Not so....upon further review of the source. Lesson learned.
I know in the grand scheme of things, it's not a big deal and we can just have multiple Checkpoint
instances, but this may be nice to mention in the README or if you REEEEEEALLY want to make this change, I'd recommend either moving the connection string parameter to the constructor of Checkpoint
instead of the Reset()
, or re-write the internals to support not "caching" the deletesql, or you can get fancy and introduce a dictionary of connection strings and tie deletesql stnts to each connection (like a "connection pool" for sql string of sorts).
I am a lazy dev, so I'd settle for an update to the README with a callout for the future me 😁
I have tried this but it does not seem to be working for me either, at least using DbConnections
private static Dictionary<string, Checkpoint> _databaseCheckpoints = new Dictionary<string, Checkpoint>();
CreateCheckPoints
using (var context = new Context1())
{
_databaseCheckpoints.Add(context.Database.Connection.Database, new Checkpoint());
}
using (var context = new Context2())
{
_databaseCheckpoints.Add(context.Database.Connection.Database, new Checkpoint());
}
using (var context = new Context3())
{
_databaseCheckpoints.Add(context.Database.Connection.Database, new Checkpoint());
}
CheckpointReset
public static void RestoreSnapshot(DbContext context)
{
var dbName = context.Database.Connection.Database;
if (_databaseCheckpoints.ContainsKey(dbName))
{
_databaseCheckpoints[dbName].Reset(context.Database.Connection);
}
}
edit - got it working by using context.Database.Connection.ConnectionString instead, plus it might have been working all along as I wasn't awaiting the reset call