Search code examples
sqliteservicestackormlite-servicestack

ServiceStack SQLite An entry with the same key already exists


When trying to upgrade from ServiceStack OrmLite v6.9.0 to 8.5.2, I encountered an exception in my test project. We use SQLite in the test project and the test project targets .NET Framework 4.8.

System.ArgumentException
An entry with the same key already exists.
   at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   at System.Collections.Generic.SortedList`2.Add(TKey key, TValue value)
   at System.Data.SQLite.SQLiteConnection.ParseConnectionString(SQLiteConnection connection, String connectionString, Boolean allowNameOnly)
   at System.Data.SQLite.SQLiteConnection.HasInMemoryDataSource(SQLiteConnection connection, String connectionString, Boolean parseViaFramework)
   at System.Data.SQLite.SQLiteConnection..ctor(String connectionString, Boolean parseViaFramework)
   at ServiceStack.OrmLite.Sqlite.SqliteOrmLiteDialectProvider.CreateConnection(String connectionString) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack.OrmLite/src/ServiceStack.OrmLite.Sqlite/SqliteOrmLiteDialectProvider.cs:line 19
   at ServiceStack.OrmLite.Sqlite.SqliteOrmLiteDialectProviderBase.CreateConnection(String connectionString, Dictionary`2 options) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack.OrmLite/src/ServiceStack.OrmLite.Sqlite/SqliteOrmLiteDialectProviderBase.cs:line 208
   at ServiceStack.OrmLite.OrmLiteConnection.get_DbConnection() in /home/runner/work/ServiceStack/ServiceStack/ServiceStack.OrmLite/src/ServiceStack.OrmLite/OrmLiteConnection.cs:line 40
   at ServiceStack.OrmLite.OrmLiteConnection.Open() in /home/runner/work/ServiceStack/ServiceStack/ServiceStack.OrmLite/src/ServiceStack.OrmLite/OrmLiteConnection.cs:line 119
   at ServiceStack.OrmLite.OrmLiteConnectionFactory.OpenDbConnection(String namedConnection) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack.OrmLite/src/ServiceStack.OrmLite/OrmLiteConnectionFactory.cs:line 195
   at ChangeTracking.Test.HighJumpLocationOrderServiceTests..ctor() in D:\TFS\Integration\Change Tracking\Dev\ChangeTracking.Test\HighJumpLocationOrderServiceTests.cs:line 38

Solution

  • The reason this broke was because ServiceStack decided to add a ConnectionStringFilter to the SQLite connection string by default. This filter does a naïve append to the user-specified connection string of "Version=3;New=True;Compress=True". My connection strings were all in the format "Data Source=dbPath.db;Version=3;Pooling=True;Max Pool Size=100;Journal Mode=Off;". Because I already had Version=3 in my string, OrmLite was appending it again, which caused SQLite to see it as a duplicate entry.

    To fix this, I set the connection string filter to null so this default behavior is not exhibited.

    SqliteDialectProvider.Instance.ConnectionStringFilter = null;