using MongoDB.Driver; using MongoDB.Driver.Linq; using MongoDbGenericRepository.DataAccess.Base; using MongoDbGenericRepository.Models; using MongoDbGenericRepository.Utils; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace MongoDbGenericRepository.DataAccess.Create { public class MongoDbCreator : DataAccessBase { public MongoDbCreator(IMongoDbContext mongoDbContext) : base(mongoDbContext) { } #region Create TKey /// /// Asynchronously adds a document to the collection. /// Populates the Id and AddedAtUtc fields if necessary. /// /// The type representing a Document. /// The type of the primary key for a Document. /// The document you want to add. public virtual async Task AddOneAsync(TDocument document) where TDocument : IDocument where TKey : IEquatable { FormatDocument(document); await HandlePartitioned(document).InsertOneAsync(document); } /// /// Adds a document to the collection. /// Populates the Id and AddedAtUtc fields if necessary. /// /// The type representing a Document. /// The type of the primary key for a Document. /// The document you want to add. public virtual void AddOne(TDocument document) where TDocument : IDocument where TKey : IEquatable { FormatDocument(document); HandlePartitioned(document).InsertOne(document); } /// /// Asynchronously adds a list of documents to the collection. /// Populates the Id and AddedAtUtc fields if necessary. /// /// The type representing a Document. /// The type of the primary key for a Document. /// The documents you want to add. public virtual async Task AddManyAsync(IEnumerable documents) where TDocument : IDocument where TKey : IEquatable { if (!documents.Any()) { return; } foreach (var document in documents) { FormatDocument(document); } // cannot use typeof(IPartitionedDocument).IsAssignableFrom(typeof(TDocument)), not available in netstandard 1.5 if (documents.Any(e => e is IPartitionedDocument)) { foreach (var group in documents.GroupBy(e => ((IPartitionedDocument)e).PartitionKey)) { await HandlePartitioned(group.FirstOrDefault()).InsertManyAsync(group.ToList()); } } else { await GetCollection().InsertManyAsync(documents.ToList()); } } /// /// Adds a list of documents to the collection. /// Populates the Id and AddedAtUtc fields if necessary. /// /// The type representing a Document. /// The type of the primary key for a Document. /// The documents you want to add. public virtual void AddMany(IEnumerable documents) where TDocument : IDocument where TKey : IEquatable { if (!documents.Any()) { return; } foreach (var document in documents) { FormatDocument(document); } // cannot use typeof(IPartitionedDocument).IsAssignableFrom(typeof(TDocument)), not available in netstandard 1.5 if (documents.Any(e => e is IPartitionedDocument)) { foreach (var group in documents.GroupBy(e => ((IPartitionedDocument)e).PartitionKey)) { HandlePartitioned(group.FirstOrDefault()).InsertMany(group.ToList()); } } else { GetCollection().InsertMany(documents.ToList()); } } #endregion /// /// Sets the value of the document Id if it is not set already. /// /// The document type. /// The type of the primary key. /// The document. protected void FormatDocument(TDocument document) where TDocument : IDocument where TKey : IEquatable { if (document == null) { throw new ArgumentNullException(nameof(document)); } var defaultTKey = default(TKey); if (document.Id == null || (defaultTKey != null && defaultTKey.Equals(document.Id))) { document.Id = IdGenerator.GetId(); } } } }