diff --git a/src/Squidex.Domain.Apps.Entities.MongoDb/Apps/MongoAppEntity.cs b/src/Squidex.Domain.Apps.Entities.MongoDb/Apps/MongoAppEntity.cs index dfc59ef16..1dcf33b80 100644 --- a/src/Squidex.Domain.Apps.Entities.MongoDb/Apps/MongoAppEntity.cs +++ b/src/Squidex.Domain.Apps.Entities.MongoDb/Apps/MongoAppEntity.cs @@ -14,7 +14,7 @@ using Squidex.Infrastructure.MongoDb; namespace Squidex.Domain.Apps.Entities.MongoDb.Apps { - public sealed class MongoAppEntity + public sealed class MongoAppEntity : IVersionedEntity { [BsonId] [BsonElement] @@ -28,7 +28,7 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Apps [BsonElement] [BsonRequired] - public int Version { get; set; } + public long Version { get; set; } [BsonElement] [BsonRequired] diff --git a/src/Squidex.Domain.Apps.Entities.MongoDb/Apps/MongoAppRepository_SnapshotStore.cs b/src/Squidex.Domain.Apps.Entities.MongoDb/Apps/MongoAppRepository_SnapshotStore.cs index c040a9fa8..54212eb19 100644 --- a/src/Squidex.Domain.Apps.Entities.MongoDb/Apps/MongoAppRepository_SnapshotStore.cs +++ b/src/Squidex.Domain.Apps.Entities.MongoDb/Apps/MongoAppRepository_SnapshotStore.cs @@ -12,6 +12,7 @@ using System.Threading.Tasks; using MongoDB.Driver; using Squidex.Domain.Apps.Entities.Apps.State; using Squidex.Infrastructure; +using Squidex.Infrastructure.MongoDb; using Squidex.Infrastructure.States; namespace Squidex.Domain.Apps.Entities.MongoDb.Apps @@ -32,36 +33,12 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Apps return (null, EtagVersion.NotFound); } - public async Task WriteAsync(Guid key, AppState value, long oldVersion, long newVersion) + public Task WriteAsync(Guid key, AppState value, long oldVersion, long newVersion) { - try - { - await Collection.UpdateOneAsync(x => x.Id == key && x.Version == oldVersion, - Update - .Set(x => x.UserIds, value.Contributors.Keys.ToArray()) - .Set(x => x.Name, value.Name) - .Set(x => x.State, value) - .Set(x => x.Version, newVersion), - Upsert); - } - catch (MongoWriteException ex) - { - if (ex.WriteError.Category == ServerErrorCategory.DuplicateKey) - { - var existingVersion = - await Collection.Find(x => x.Id == key) - .Project(Projection.Exclude(x => x.Id)).FirstOrDefaultAsync(); - - if (existingVersion != null) - { - throw new InconsistentStateException(existingVersion.Version, oldVersion, ex); - } - } - else - { - throw; - } - } + return Collection.UpsertVersionedAsync(key, oldVersion, newVersion, u => u + .Set(x => x.Name, value.Name) + .Set(x => x.State, value) + .Set(x => x.UserIds, value.Contributors.Keys.ToArray())); } } } diff --git a/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetEntity.cs b/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetEntity.cs index 923669eb0..23f91b825 100644 --- a/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetEntity.cs +++ b/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetEntity.cs @@ -10,10 +10,11 @@ using System; using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; using Squidex.Domain.Apps.Entities.Assets.State; +using Squidex.Infrastructure.MongoDb; namespace Squidex.Domain.Apps.Entities.MongoDb.Assets { - public sealed class MongoAssetEntity + public sealed class MongoAssetEntity : IVersionedEntity { [BsonId] [BsonElement] @@ -26,6 +27,6 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Assets [BsonElement] [BsonRequired] - public int Version { get; set; } + public long Version { get; set; } } } diff --git a/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository_SnapshotStore.cs b/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository_SnapshotStore.cs index 70355a5bf..a4bd4c198 100644 --- a/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository_SnapshotStore.cs +++ b/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository_SnapshotStore.cs @@ -32,34 +32,9 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Assets return (null, EtagVersion.NotFound); } - public async Task WriteAsync(Guid key, AssetState value, long oldVersion, long newVersion) + public Task WriteAsync(Guid key, AssetState value, long oldVersion, long newVersion) { - try - { - await Collection.UpdateOneAsync(x => x.Id == key && x.Version == oldVersion, - Update - .Set(x => x.State, value) - .Set(x => x.Version, newVersion), - Upsert); - } - catch (MongoWriteException ex) - { - if (ex.WriteError.Category == ServerErrorCategory.DuplicateKey) - { - var existingVersion = - await Collection.Find(x => x.Id == key).Only(x => x.Id, x => x.Version) - .FirstOrDefaultAsync(); - - if (existingVersion != null) - { - throw new InconsistentStateException(existingVersion["Version"].AsInt64, oldVersion, ex); - } - } - else - { - throw; - } - } + return Collection.UpsertVersionedAsync(key, oldVersion, newVersion, u => u.Set(x => x.State, value)); } } } diff --git a/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentEntity.cs b/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentEntity.cs index bb5c32a58..67a838025 100644 --- a/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentEntity.cs +++ b/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentEntity.cs @@ -87,10 +87,6 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents [BsonElement("mb")] public RefToken LastModifiedBy { get; set; } - [BsonRequired] - [BsonElement("lt")] - public bool IsLatest { get; set; } - [BsonIgnore] public NamedContentData Data { diff --git a/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository.cs b/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository.cs index dbdad15dc..51b00cc52 100644 --- a/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository.cs +++ b/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository.cs @@ -26,6 +26,12 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents public partial class MongoContentRepository : MongoRepositoryBase, IContentRepository { private readonly IAppProvider appProvider; + private readonly IMongoCollection archiveCollection; + + protected IMongoCollection ArchiveCollection + { + get { return archiveCollection; } + } public MongoContentRepository(IMongoDatabase database, IAppProvider appProvider) : base(database) @@ -33,6 +39,8 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents Guard.NotNull(appProvider, nameof(appProvider)); this.appProvider = appProvider; + + archiveCollection = database.GetCollection("States_Contents_Archive"); } protected override string CollectionName() @@ -42,25 +50,23 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents protected override async Task SetupCollectionAsync(IMongoCollection collection) { - await collection.Indexes.CreateOneAsync( + await archiveCollection.Indexes.CreateOneAsync( Index .Ascending(x => x.Id) .Ascending(x => x.Version)); await collection.Indexes.CreateOneAsync( Index - .Ascending(x => x.Id) - .Descending(x => x.Version)); + .Ascending(x => x.SchemaId) + .Ascending(x => x.Status) + .Text(x => x.DataText)); await collection.Indexes.CreateOneAsync( Index - .Ascending(x => x.SchemaId) - .Descending(x => x.IsLatest) - .Descending(x => x.LastModified)); + .Ascending(x => x.Id) + .Ascending(x => x.Version)); await collection.Indexes.CreateOneAsync(Index.Ascending(x => x.ReferencedIds)); - await collection.Indexes.CreateOneAsync(Index.Ascending(x => x.Status)); - await collection.Indexes.CreateOneAsync(Index.Text(x => x.DataText)); } public async Task> QueryAsync(IAppEntity app, ISchemaEntity schema, Status[] status, ODataUriParser odataQuery) @@ -94,7 +100,7 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents public async Task> QueryAsync(IAppEntity app, ISchemaEntity schema, Status[] status, HashSet ids) { - var find = Collection.Find(x => ids.Contains(x.Id) && x.IsLatest); + var find = Collection.Find(x => ids.Contains(x.Id)); var contentItems = find.ToListAsync(); var contentCount = find.CountAsync(); @@ -121,7 +127,7 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents public async Task FindContentAsync(IAppEntity app, ISchemaEntity schema, Guid id, long version) { var contentEntity = - await Collection.Find(x => x.Id == id && x.Version >= version).SortBy(x => x.Version) + await ArchiveCollection.Find(x => x.Id == id && x.Version >= version).SortBy(x => x.Version) .FirstOrDefaultAsync(); contentEntity?.ParseData(schema.SchemaDef); @@ -132,7 +138,7 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents public async Task FindContentAsync(IAppEntity app, ISchemaEntity schema, Guid id) { var contentEntity = - await Collection.Find(x => x.Id == id && x.IsLatest) + await Collection.Find(x => x.Id == id) .FirstOrDefaultAsync(); contentEntity?.ParseData(schema.SchemaDef); diff --git a/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository_SnapshotStore.cs b/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository_SnapshotStore.cs index a96ad0b51..a0c3cf091 100644 --- a/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository_SnapshotStore.cs +++ b/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository_SnapshotStore.cs @@ -41,8 +41,6 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents public async Task WriteAsync(Guid key, ContentState value, long oldVersion, long newVersion) { - var documentId = $"{key}_{newVersion}"; - if (value.SchemaId == Guid.Empty) { return; @@ -52,12 +50,13 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents var idData = value.Data?.ToIdModel(schema.SchemaDef, true); + var id = key.ToString(); + var document = SimpleMapper.Map(value, new MongoContentEntity { - DocumentId = documentId, + DocumentId = key.ToString(), DataText = idData?.ToFullText(), DataByIds = idData, - IsLatest = !value.IsDeleted, ReferencedIds = idData?.ToReferencedIds(schema.SchemaDef), }); @@ -65,15 +64,14 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents try { - await Collection.InsertOneAsync(document); - await Collection.UpdateManyAsync(x => x.Id == value.Id && x.Version < value.Version, Update.Set(x => x.IsLatest, false)); + await Collection.ReplaceOneAsync(x => x.DocumentId == id && x.Version == oldVersion, document, Upsert); } catch (MongoWriteException ex) { if (ex.WriteError.Category == ServerErrorCategory.DuplicateKey) { var existingVersion = - await Collection.Find(x => x.Id == value.Id && x.IsLatest).Only(x => x.Id, x => x.Version) + await Collection.Find(x => x.DocumentId == id).Only(x => x.DocumentId, x => x.Version) .FirstOrDefaultAsync(); if (existingVersion != null) @@ -86,6 +84,10 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents throw; } } + + document.DocumentId = $"{key}_{newVersion}"; + + await ArchiveCollection.ReplaceOneAsync(x => x.DocumentId == document.DocumentId, document, Upsert); } private async Task GetSchemaAsync(Guid appId, Guid schemaId) diff --git a/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Visitors/FindExtensions.cs b/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Visitors/FindExtensions.cs index 12e1f3262..84d8f1221 100644 --- a/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Visitors/FindExtensions.cs +++ b/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Visitors/FindExtensions.cs @@ -68,7 +68,6 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Visitors var filters = new List> { Filter.Eq(x => x.SchemaId, schemaId), - Filter.Eq(x => x.IsLatest, true), Filter.In(x => x.Status, status) }; diff --git a/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEntity.cs b/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEntity.cs index dbd3cb926..fe4e45601 100644 --- a/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEntity.cs +++ b/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEntity.cs @@ -14,7 +14,7 @@ using Squidex.Infrastructure.MongoDb; namespace Squidex.Domain.Apps.Entities.MongoDb.Rules { - public sealed class MongoRuleEntity + public sealed class MongoRuleEntity : IVersionedEntity { [BsonId] [BsonElement] @@ -33,7 +33,7 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Rules [BsonElement] [BsonRequired] - public int Version { get; set; } + public long Version { get; set; } [BsonElement] [BsonRequired] diff --git a/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleRepository_SnapshotStore.cs b/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleRepository_SnapshotStore.cs index faa7d0783..dd7737c02 100644 --- a/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleRepository_SnapshotStore.cs +++ b/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleRepository_SnapshotStore.cs @@ -32,36 +32,12 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Rules return (null, EtagVersion.NotFound); } - public async Task WriteAsync(Guid key, RuleState value, long oldVersion, long newVersion) + public Task WriteAsync(Guid key, RuleState value, long oldVersion, long newVersion) { - try - { - await Collection.UpdateOneAsync(x => x.Id == key && x.Version == oldVersion, - Update - .Set(x => x.State, value) - .Set(x => x.AppId, value.AppId) - .Set(x => x.IsDeleted, value.IsDeleted) - .Set(x => x.Version, newVersion), - Upsert); - } - catch (MongoWriteException ex) - { - if (ex.WriteError.Category == ServerErrorCategory.DuplicateKey) - { - var existingVersion = - await Collection.Find(x => x.Id == key).Only(x => x.Id, x => x.Version) - .FirstOrDefaultAsync(); - - if (existingVersion != null) - { - throw new InconsistentStateException(existingVersion["Version"].AsInt64, oldVersion, ex); - } - } - else - { - throw; - } - } + return Collection.UpsertVersionedAsync(key, oldVersion, newVersion, u => u + .Set(x => x.State, value) + .Set(x => x.AppId, value.AppId) + .Set(x => x.IsDeleted, value.IsDeleted)); } } } diff --git a/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemaEntity.cs b/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemaEntity.cs index 97aa996ad..5abaeee7b 100644 --- a/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemaEntity.cs +++ b/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemaEntity.cs @@ -14,7 +14,7 @@ using Squidex.Infrastructure.MongoDb; namespace Squidex.Domain.Apps.Entities.MongoDb.Schemas { - public sealed class MongoSchemaEntity + public sealed class MongoSchemaEntity : IVersionedEntity { [BsonId] [BsonElement] @@ -37,7 +37,7 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Schemas [BsonElement] [BsonRequired] - public int Version { get; set; } + public long Version { get; set; } [BsonElement] [BsonRequired] diff --git a/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemaRepository_SnapshotStore.cs b/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemaRepository_SnapshotStore.cs index ba8e6a93e..db0a76a25 100644 --- a/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemaRepository_SnapshotStore.cs +++ b/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemaRepository_SnapshotStore.cs @@ -32,37 +32,13 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Schemas return (null, EtagVersion.NotFound); } - public async Task WriteAsync(Guid key, SchemaState value, long oldVersion, long newVersion) + public Task WriteAsync(Guid key, SchemaState value, long oldVersion, long newVersion) { - try - { - await Collection.UpdateOneAsync(x => x.Id == key && x.Version == oldVersion, - Update - .Set(x => x.State, value) - .Set(x => x.AppId, value.AppId) - .Set(x => x.Name, value.Name) - .Set(x => x.Version, newVersion) - .Set(x => x.IsDeleted, value.IsDeleted), - Upsert); - } - catch (MongoWriteException ex) - { - if (ex.WriteError.Category == ServerErrorCategory.DuplicateKey) - { - var existingVersion = - await Collection.Find(x => x.Id == key).Only(x => x.Version) - .FirstOrDefaultAsync(); - - if (existingVersion != null) - { - throw new InconsistentStateException(existingVersion["Version"].AsInt64, oldVersion, ex); - } - } - else - { - throw; - } - } + return Collection.UpsertVersionedAsync(key, oldVersion, newVersion, u => u + .Set(x => x.State, value) + .Set(x => x.AppId, value.AppId) + .Set(x => x.Name, value.Name) + .Set(x => x.IsDeleted, value.IsDeleted)); } } } diff --git a/src/Squidex.Infrastructure.MongoDb/MongoDb/IVersionedEntity.cs b/src/Squidex.Infrastructure.MongoDb/MongoDb/IVersionedEntity.cs new file mode 100644 index 000000000..d925df089 --- /dev/null +++ b/src/Squidex.Infrastructure.MongoDb/MongoDb/IVersionedEntity.cs @@ -0,0 +1,16 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +namespace Squidex.Infrastructure.MongoDb +{ + public interface IVersionedEntity + { + T Id { get; set; } + + long Version { get; set; } + } +} diff --git a/src/Squidex.Infrastructure.MongoDb/MongoDb/MongoExtensions.cs b/src/Squidex.Infrastructure.MongoDb/MongoDb/MongoExtensions.cs index 8a8d068bf..244e3b88e 100644 --- a/src/Squidex.Infrastructure.MongoDb/MongoDb/MongoExtensions.cs +++ b/src/Squidex.Infrastructure.MongoDb/MongoDb/MongoExtensions.cs @@ -11,11 +11,14 @@ using System.Linq.Expressions; using System.Threading.Tasks; using MongoDB.Bson; using MongoDB.Driver; +using Squidex.Infrastructure.States; namespace Squidex.Infrastructure.MongoDb { public static class MongoExtensions { + private static readonly UpdateOptions Upsert = new UpdateOptions { IsUpsert = true }; + public static async Task InsertOneIfNotExistsAsync(this IMongoCollection collection, T document) { try @@ -55,5 +58,62 @@ namespace Squidex.Infrastructure.MongoDb { return find.Project(Builders.Projection.Include(include1).Include(include2).Include(include3)); } + + public static async Task UpsertVersionedAsync(this IMongoCollection collection, TKey key, long oldVersion, long newVersion, Func, UpdateDefinition> updater) where T : IVersionedEntity + { + try + { + var update = updater(Builders.Update.Set(x => x.Version, newVersion)); + + await collection.UpdateOneAsync(x => x.Id.Equals(key) && x.Version == oldVersion, + update + .Set(x => x.Version, newVersion), + Upsert); + } + catch (MongoWriteException ex) + { + if (ex.WriteError.Category == ServerErrorCategory.DuplicateKey) + { + var existingVersion = + await collection.Find(x => x.Id.Equals(key)).Only(x => x.Id, x => x.Version) + .FirstOrDefaultAsync(); + + if (existingVersion != null) + { + throw new InconsistentStateException(existingVersion[nameof(IVersionedEntity.Version)].AsInt64, oldVersion, ex); + } + } + else + { + throw; + } + } + } + + public static async Task UpsertVersionedAsync(this IMongoCollection collection, TKey key, long oldVersion, long newVersion, T doc) where T : IVersionedEntity + { + try + { + await collection.ReplaceOneAsync(x => x.Id.Equals(key) && x.Version == oldVersion, doc, Upsert); + } + catch (MongoWriteException ex) + { + if (ex.WriteError.Category == ServerErrorCategory.DuplicateKey) + { + var existingVersion = + await collection.Find(x => x.Id.Equals(key)).Only(x => x.Id, x => x.Version) + .FirstOrDefaultAsync(); + + if (existingVersion != null) + { + throw new InconsistentStateException(existingVersion[nameof(IVersionedEntity.Version)].AsInt64, oldVersion, ex); + } + } + else + { + throw; + } + } + } } } diff --git a/src/Squidex.Infrastructure.MongoDb/States/MongoSnapshotStore.cs b/src/Squidex.Infrastructure.MongoDb/States/MongoSnapshotStore.cs index bbdb89a98..c80c8dbd9 100644 --- a/src/Squidex.Infrastructure.MongoDb/States/MongoSnapshotStore.cs +++ b/src/Squidex.Infrastructure.MongoDb/States/MongoSnapshotStore.cs @@ -44,34 +44,9 @@ namespace Squidex.Infrastructure.States return (default(T), EtagVersion.NotFound); } - public async Task WriteAsync(TKey key, T value, long oldVersion, long newVersion) + public Task WriteAsync(TKey key, T value, long oldVersion, long newVersion) { - try - { - await Collection.UpdateOneAsync(x => Equals(x.Id, key) && x.Version == oldVersion, - Update - .Set(x => x.Doc, value) - .Set(x => x.Version, newVersion), - Upsert); - } - catch (MongoWriteException ex) - { - if (ex.WriteError.Category == ServerErrorCategory.DuplicateKey) - { - var existingVersion = - await Collection.Find(x => Equals(x.Id, key)).Only(x => x.Id, x => x.Version) - .FirstOrDefaultAsync(); - - if (existingVersion != null) - { - throw new InconsistentStateException(existingVersion["Version"].AsInt64, oldVersion, ex); - } - } - else - { - throw; - } - } + return Collection.UpsertVersionedAsync(key, oldVersion, newVersion, u => u.Set(x => x.Doc, value)); } } } diff --git a/src/Squidex.Infrastructure.MongoDb/States/MongoState.cs b/src/Squidex.Infrastructure.MongoDb/States/MongoState.cs index 6a62139fc..682b092bc 100644 --- a/src/Squidex.Infrastructure.MongoDb/States/MongoState.cs +++ b/src/Squidex.Infrastructure.MongoDb/States/MongoState.cs @@ -12,7 +12,7 @@ using Squidex.Infrastructure.MongoDb; namespace Squidex.Infrastructure.States { - public sealed class MongoState + public sealed class MongoState : IVersionedEntity { [BsonId] [BsonElement]