# SQL Persistence Upgrade Version 1 to 2 ## Subscription Caching configuration now required [Subscription Caching](/persistence/sql/subscriptions.md) is now a required configuration option. Either configure a time to cache for: ```csharp var persistence = endpointConfiguration.UsePersistence(); var subscriptions = persistence.SubscriptionSettings(); subscriptions.CacheFor(TimeSpan.FromMinutes(1)); ``` Or explicitly disable the subscription caching. ```csharp var persistence = endpointConfiguration.UsePersistence(); var subscriptions = persistence.SubscriptionSettings(); subscriptions.DisableCache(); ``` ## Inheriting from SqlSaga now required In Version 1, inheriting from `NServiceBus.Saga` was partially supported. However, this has two competing approaches that deliver the same features, causing significant confusion. In Version 2, `NServiceBus.Saga` is no longer supported, and either a build error, or a runtime exception for some edge cases will occur. ## Deep nested Saga hierarchies are no longer supported In Version 1, having deep class hierarchies inheriting from `SqlSaga` was supported. This scenario is no longer supported, and all sagas **must** inherit directly from `SqlSaga`. This decision was made to bring the SQL persistence inline with the future design of NServiceBus. ## Correlation Property The API for defining a Correlation Property has been moved from an attribute to a property at the saga class level. ```csharp // For Sql Persistence version 2.x public class MySaga : SqlSaga, IAmStartedByMessages { protected override string CorrelationPropertyName => nameof(SagaData.TheId); // For Sql Persistence version 1.x [SqlSaga( correlationProperty: nameof(SagaData.TheId) )] public class MySaga : SqlSaga, IAmStartedByMessages { ``` ## Message Mapping The API to define message mapping has been changed to bring it in line with the future design of NServiceBus: * `MapMessage` renamed to `ConfigureMapping`. * `MessagePropertyMapper` renamed to `IMessagePropertyMapper`. ```csharp // For Sql Persistence version 2.x protected override void ConfigureMapping(IMessagePropertyMapper mapper) { mapper.ConfigureMapping(_ => _.TheId); } // For Sql Persistence version 1.x protected override void ConfigureMapping(MessagePropertyMapper mapper) { mapper.MapMessage(_ => _.TheId); } ``` ## SqlSaga.ConfigureMapping made abstract To simplify implementing a saga using `SqlSaga` class, the method `SqlSaga.ConfigureMapping` has been turned into an abstract method which now needs to be implemented even if no message mapping is required. ## SqlPersistenceSettingsAttribute move to use properties Attributes have been moved to use properties instead of optional parameters in the constructor. ```csharp // For Sql Persistence version 2.x [assembly: SqlPersistenceSettings( MsSqlServerScripts = true, MySqlScripts = true)] // For Sql Persistence version 1.x [assembly: SqlPersistenceSettings( msSqlServerScripts: true, mySqlScripts: true)] ``` ## SqlSagaAttribute made obsolete The `[SqlSagaAttribute]` has been made obsolete and replaced by property overrides on the `SqlSaga` class. ```csharp // For Sql Persistence version 2.x public class MySaga : SqlSaga { protected override string CorrelationPropertyName => nameof(SagaData.CorrelationProperty); protected override string TransitionalCorrelationPropertyName => nameof(SagaData.TransitionalCorrelationProperty); protected override string TableSuffix => "TheCustomTableName"; // For Sql Persistence version 1.x [SqlSaga( tableSuffix: "TheCustomTableName", transitionalCorrelationProperty: "OtherPropertyName" )] ``` ## Explicit schema API An explicit schema API has been added. ```csharp // For Sql Persistence version 2.x var persistence = endpointConfiguration.UsePersistence(); persistence.Schema("MySchema"); // For Sql Persistence version 1.x var persistence = endpointConfiguration.UsePersistence(); persistence.TablePrefix("MySchema."); ``` If characters that required quoting were previously used in the table prefix, they can be removed and the following can be used instead: ```csharp // For Sql Persistence version 2.x var persistence = endpointConfiguration.UsePersistence(); persistence.Schema("My Schema"); // For Sql Persistence version 1.x var persistence = endpointConfiguration.UsePersistence(); persistence.TablePrefix("[My Schema]."); ``` > [!WARNING] > An exception will be thrown if any of ], [ or ` are detected in the `tablePrefix` or the schema. ## Missing Indexes Some missing indexes have been added. These indexes will be added the next time the [installers](/persistence/sql/install.md) are executed. No explicit SQL migration is required. ### TimeoutData * Add missing non-unique index on `Time`, which is used to query expired timeouts. * Add missing non-unique index on `SagaId`, which is used to clean timeouts of the completed sagas. ### OutboxData * Add missing index on `Dispatched (bool)` * Add missing index on `DispatchedAt (datetime)`