public MongoMetadata(string connectionString, MongoConfiguration.Metadata metadata = null) { this.connectionString = connectionString; this.Configuration = metadata ?? MongoConfiguration.Metadata.Default; lock (MetadataCache) { MongoMetadataCache metadataCache; MetadataCache.TryGetValue(this.connectionString, out metadataCache); if (metadataCache == null) { metadataCache = new MongoMetadataCache { DspMetadata = new DSPMetadata(ContainerName, RootNamespace), ProviderTypes = new Dictionary<string, Type>() }; MetadataCache.Add(this.connectionString, metadataCache); } this.dspMetadata = metadataCache.DspMetadata; this.providerTypes = metadataCache.ProviderTypes; } using (var context = new MongoContext(connectionString)) { PopulateMetadata(context); } }
public MongoMetadata(string connectionString, MongoConfiguration.Metadata metadata = null) { _connectionString = connectionString; this.Configuration = metadata ?? MongoConfiguration.Metadata.Default; lock (s_metadataCache) { _instanceMetadataCache = GetOrCreateMetadataCache(); } var context = new MongoContext(connectionString); PopulateMetadata(context); }
public override void SaveChanges() { base.SaveChanges(); MongoContext mongoContext = new MongoContext(_connectionString); foreach (var pendingChange in _pendingChanges) { var action = pendingChange.Action; action(mongoContext, pendingChange); } _pendingChanges.Clear(); }
public override void SaveChanges() { base.SaveChanges(); using (MongoContext mongoContext = new MongoContext(connectionString)) { foreach (var pendingChange in this.pendingChanges) { var action = pendingChange.Action; action(mongoContext, pendingChange); } } this.pendingChanges.Clear(); }
private ResourceSet AddResourceSet(MongoContext context, string collectionName, BsonDocument document = null) { AddDocumentType(context, collectionName, document, ResourceTypeKind.EntityType); return _instanceMetadataCache.ResolveResourceSet(collectionName); }
private void PopulateMetadata(MongoContext context) { foreach (var collectionName in GetCollectionNames(context)) { var collection = context.Database.GetCollection(collectionName); var resourceSet = this.dspMetadata.ResourceSets.SingleOrDefault(x => x.Name == collectionName); var documents = collection.FindAll(); if (this.Configuration.PrefetchRows == 0) { if (resourceSet == null) { RegisterResourceSet(context, collectionName); } } else { int rowCount = 0; foreach (var document in documents) { if (resourceSet == null) { resourceSet = RegisterResourceSet(context, collectionName, document); } else { UpdateResourceSet(context, resourceSet, document); } ++rowCount; if (this.Configuration.PrefetchRows >= 0 && rowCount >= this.Configuration.PrefetchRows) break; } } } }
private void RemoveDocument(MongoContext mongoContext, ResourceChange change) { var collection = mongoContext.Database.GetCollection(change.CollectionName); var query = Query.EQ(MongoMetadata.ProviderObjectIdName, ObjectId.Parse(change.Resource.GetValue(MongoMetadata.MappedObjectIdName).ToString())); collection.Remove(query); }
private void RegisterDocumentProperty(MongoContext context, ResourceType resourceType, BsonElement element) { var resourceProperty = ResolveResourceProperty(resourceType, element); if (resourceProperty == null) { RegisterResourceProperty(context, resourceType, element); } else if ((resourceProperty.Kind & ResourcePropertyKind.ComplexType) != 0 && element.Value != BsonNull.Value) { RegisterDocumentProperties(context, resourceType, element); } else if ((resourceProperty.Kind & ResourcePropertyKind.Collection) != 0 && element.Value != BsonNull.Value) { RegisterArrayProperty(context, resourceType, element); } }
private void RegisterArrayProperty(MongoContext context, ResourceType collectionType, BsonElement element) { var propertyName = GetResourcePropertyName(element, ResourceTypeKind.EntityType); var bsonArray = element.Value.AsBsonArray; if (bsonArray != null) { foreach (var arrayValue in bsonArray) { if (arrayValue.AsBsonValue == BsonNull.Value) continue; if (arrayValue.BsonType == BsonType.Document) { RegisterDocumentProperties(context, collectionType, new BsonElement(element.Name, arrayValue)); } else if (ResolveResourceProperty(collectionType, propertyName) == null) { // OData protocol doesn't support collections of collections if (arrayValue.BsonType != BsonType.Array) { var mappedType = BsonTypeMapper.MapToDotNetValue(arrayValue).GetType(); _instanceMetadataCache.AddCollectionProperty(collectionType, propertyName, mappedType); } } } } }
private void UpdateDocument(MongoContext mongoContext, ResourceChange change) { if (!change.ModifiedProperties.Any()) return; var collection = mongoContext.Database.GetCollection<BsonDocument>(change.CollectionName); var filter = Builders<BsonDocument>.Filter.Eq(MongoMetadata.ProviderObjectIdName, ObjectId.Parse(change.Resource.GetValue(MongoMetadata.MappedObjectIdName).ToString())); UpdateDefinition<BsonDocument> update = null; foreach (var resourceProperty in change.ModifiedProperties) { if (update == null) { if (resourceProperty.Value != null) { update = Builders<BsonDocument>.Update.Set(resourceProperty.Key, BsonValue.Create(resourceProperty.Value)); } else { update = Builders<BsonDocument>.Update.Unset(resourceProperty.Key); } } else { if (resourceProperty.Value != null) { update = update.Set(resourceProperty.Key, BsonValue.Create(resourceProperty.Value)); } else { update = update.Unset(resourceProperty.Key); } } } collection.UpdateOneAsync(filter, update).GetAwaiter().GetResult(); }
private void RemoveDocument(MongoContext mongoContext, ResourceChange change) { var collection = mongoContext.Database.GetCollection<BsonDocument>(change.CollectionName); var filter = Builders<BsonDocument>.Filter.Eq(MongoMetadata.ProviderObjectIdName, ObjectId.Parse(change.Resource.GetValue(MongoMetadata.MappedObjectIdName).ToString())); collection.DeleteOneAsync(filter).GetAwaiter().GetResult(); }
private void UpdateResourceSet(MongoContext context, ResourceSet resourceSet, BsonDocument document) { foreach (var element in document.Elements) { var propertyName = GetResourcePropertyName(element); var resourceProperty = resourceSet.ResourceType.Properties.Where(x => x.Name == propertyName).SingleOrDefault(); if (resourceProperty == null) { var elementType = GetElementType(element); RegisterResourceProperty(context, resourceSet.Name, resourceSet.ResourceType, elementType, element, ResourceTypeKind.EntityType); } } }
private ResourceSet RegisterResourceSet(MongoContext context, string collectionName, BsonDocument document = null) { RegisterResourceType(context, collectionName, document, ResourceTypeKind.EntityType); return this.dspMetadata.ResourceSets.SingleOrDefault(x => x.Name == collectionName); }
private void RegisterResourceProperty(MongoContext context, string collectionName, ResourceType collectionType, Type elementType, BsonElement element, ResourceTypeKind resourceTypeKind) { if (ResolveProviderType(element.Value) == null) return; string propertyName = element.Name; var propertyValue = element.Value; var isKey = false; if (IsObjectId(element)) { propertyName = MongoMetadata.MappedObjectIdName; if (resourceTypeKind == ResourceTypeKind.EntityType) this.dspMetadata.AddKeyProperty(collectionType, propertyName, elementType); else this.dspMetadata.AddPrimitiveProperty(collectionType, propertyName, elementType); isKey = true; } else if (elementType == typeof(BsonDocument)) { ResourceType resourceType = null; var resourceSet = this.dspMetadata.ResourceSets.SingleOrDefault(x => x.Name == propertyName); if (resourceSet != null) { resourceType = resourceSet.ResourceType; } else { resourceType = RegisterResourceType(context, GetComplexTypeName(collectionName, propertyName), element.Value.AsBsonDocument, ResourceTypeKind.ComplexType); } this.dspMetadata.AddComplexProperty(collectionType, propertyName, resourceType); } else if (elementType == typeof(BsonArray)) { var bsonArray = element.Value.AsBsonArray; if (bsonArray != null && bsonArray.Count > 0) { var arrayElement = bsonArray.First(); if (arrayElement.BsonType == BsonType.Document) { ResourceType resourceType = null; var resourceSet = this.dspMetadata.ResourceSets.SingleOrDefault(x => x.Name == propertyName); if (resourceSet != null) { resourceType = resourceSet.ResourceType; } else { resourceType = RegisterResourceType(context, GetCollectionTypeName(collectionName, propertyName), arrayElement.AsBsonDocument, ResourceTypeKind.ComplexType); } this.dspMetadata.AddCollectionProperty(collectionType, propertyName, resourceType); } else { this.dspMetadata.AddCollectionProperty(collectionType, propertyName, arrayElement.RawValue.GetType()); } } } else { this.dspMetadata.AddPrimitiveProperty(collectionType, propertyName, elementType); } if (!string.IsNullOrEmpty(propertyName)) { AddProviderType(collectionName, propertyName, propertyValue, isKey); } }
private IEnumerable<string> GetCollectionNames(MongoContext context) { var collectionNamesCursor = context.Database.ListCollectionsAsync().GetAwaiter().GetResult(); var collections = collectionNamesCursor.ToListAsync().GetAwaiter().GetResult(); var collectionNames = collections.Select(y => y["name"].AsString).Where(x => !x.StartsWith("system.")); return collectionNames; }
private IEnumerable<string> GetCollectionNames(MongoContext context) { return context.Database.GetCollectionNames().Where(x => !x.StartsWith("system.")); }
private void PopulateMetadata(MongoContext context) { var collectionNames = GetCollectionNames(context); lock (_instanceMetadataCache) { foreach (var collectionName in collectionNames) { var resourceSet = _instanceMetadataCache.ResolveResourceSet(collectionName); if (this.Configuration.PrefetchRows == 0) { if (resourceSet == null) { AddResourceSet(context, collectionName); } } else { PopulateMetadataFromCollection(context, collectionName, resourceSet); } } foreach (var prop in _unresolvedProperties) { var providerType = typeof(string); var propertyName = NormalizeResourcePropertyName(prop.PropertyName); _instanceMetadataCache.AddPrimitiveProperty(prop.CollectionType, propertyName, providerType); _instanceMetadataCache.ProviderTypes.Add( GetQualifiedPropertyName(prop.CollectionType.Name, propertyName), providerType); } } }
private void PopulateMetadataFromCollection(MongoContext context, string collectionName, ResourceSet resourceSet) { var collection = context.Database.GetCollection(collectionName); const string naturalSort = "$natural"; var sortOrder = this.Configuration.FetchPosition == MongoConfiguration.FetchPosition.End ? SortBy.Descending(naturalSort) : SortBy.Ascending(naturalSort); var documents = collection.FindAll().SetSortOrder(sortOrder); int rowCount = 0; foreach (var document in documents) { if (resourceSet == null) { resourceSet = AddResourceSet(context, collectionName, document); } else { UpdateResourceSet(context, resourceSet, document); } ++rowCount; if (this.Configuration.PrefetchRows >= 0 && rowCount >= this.Configuration.PrefetchRows) break; } }
private void PopulateMetadataFromCollection(MongoContext context, string collectionName, ResourceSet resourceSet) { var collection = context.Database.GetCollection<BsonDocument>(collectionName); const string naturalSort = "$natural"; var sortBuilder = Builders<BsonDocument>.Sort; var sort = this.Configuration.FetchPosition == MongoConfiguration.FetchPosition.End ? sortBuilder.Descending(naturalSort) : sortBuilder.Ascending(naturalSort); var documents = collection.Find(new BsonDocument()).Sort(sort).ToListAsync().GetAwaiter().GetResult(); int rowCount = 0; foreach (var document in documents) { if (resourceSet == null) { resourceSet = AddResourceSet(context, collectionName, document); } else { UpdateResourceSet(context, resourceSet, document); } ++rowCount; if (this.Configuration.PrefetchRows >= 0 && rowCount >= this.Configuration.PrefetchRows) break; } }
internal void RegisterResourceProperty(MongoContext context, ResourceType resourceType, BsonElement element) { var collectionProperty = new CollectionProperty { CollectionType = resourceType, PropertyName = element.Name }; var resourceProperty = ResolveResourceProperty(resourceType, element); if (resourceProperty == null) { lock (_unresolvedProperties) { var unresolvedEarlier = _unresolvedProperties.Contains(collectionProperty); var resolvedNow = ResolveProviderType(element.Value, IsObjectId(element)) != null; if (!unresolvedEarlier && !resolvedNow) _unresolvedProperties.Add(collectionProperty); else if (unresolvedEarlier && resolvedNow) _unresolvedProperties.Remove(collectionProperty); if (resolvedNow) { AddResourceProperty(context, resourceType.Name, resourceType, element, resourceType.ResourceTypeKind == ResourceTypeKind.EntityType); } } } }
private void RegisterDocumentProperties(MongoContext context, ResourceType collectionType, BsonElement element) { var resourceName = GetResourcePropertyName(element, ResourceTypeKind.EntityType); var resourceType = ResolveResourceType(resourceName, collectionType.Name); if (resourceType == null) { AddDocumentProperty(context, collectionType.Name, collectionType, resourceName, element, true); } else { foreach (var documentElement in element.Value.AsBsonDocument.Elements) { RegisterDocumentProperty(context, resourceType, documentElement); } } }
private void AddDocumentProperty(MongoContext context, string collectionName, ResourceType collectionType, string propertyName, BsonElement element, bool isCollection = false) { ResourceType resourceType = null; var resourceSet = _instanceMetadataCache.ResolveResourceSet(collectionName); if (resourceSet != null) { resourceType = resourceSet.ResourceType; } else { resourceType = AddDocumentType(context, GetQualifiedTypeName(collectionName, propertyName), element.Value.AsBsonDocument, ResourceTypeKind.ComplexType); } if (isCollection && ResolveResourceProperty(collectionType, propertyName) == null) _instanceMetadataCache.AddCollectionProperty(collectionType, propertyName, resourceType); else _instanceMetadataCache.AddComplexProperty(collectionType, propertyName, resourceType); }
private void UpdateResourceSet(MongoContext context, ResourceSet resourceSet, BsonDocument document) { foreach (var element in document.Elements) { RegisterDocumentProperty(context, resourceSet.ResourceType, element); } }
private ResourceType AddDocumentType(MongoContext context, string collectionName, BsonDocument document, ResourceTypeKind resourceTypeKind) { var collectionType = resourceTypeKind == ResourceTypeKind.EntityType ? _instanceMetadataCache.AddEntityType(collectionName) : _instanceMetadataCache.AddComplexType(collectionName); bool hasObjectId = false; if (document != null) { foreach (var element in document.Elements) { RegisterResourceProperty(context, collectionType, element); if (IsObjectId(element)) hasObjectId = true; } } if (!hasObjectId) { if (resourceTypeKind == ResourceTypeKind.EntityType) { _instanceMetadataCache.AddKeyProperty(collectionType, MappedObjectIdName, MappedObjectIdType); } AddProviderType(collectionName, ProviderObjectIdName, BsonObjectId.Empty, true); } if (resourceTypeKind == ResourceTypeKind.EntityType) _instanceMetadataCache.AddResourceSet(collectionName, collectionType); return collectionType; }
private void UpdateDocument(MongoContext mongoContext, ResourceChange change) { if (!change.ModifiedProperties.Any()) return; var collection = mongoContext.Database.GetCollection(change.CollectionName); var query = Query.EQ(MongoMetadata.ProviderObjectIdName, ObjectId.Parse(change.Resource.GetValue(MongoMetadata.MappedObjectIdName).ToString())); UpdateBuilder update = null; foreach (var resourceProperty in change.ModifiedProperties) { if (update == null) { if (resourceProperty.Value != null) update = Update.Set(resourceProperty.Key, BsonValue.Create(resourceProperty.Value)); else update = Update.Unset(resourceProperty.Key); } else { if (resourceProperty.Value != null) update = update.Set(resourceProperty.Key, BsonValue.Create(resourceProperty.Value)); else update = update.Unset(resourceProperty.Key); } } collection.Update(query, update); }
private void AddResourceProperty(MongoContext context, string collectionName, ResourceType collectionType, BsonElement element, bool treatObjectIdAsKey = false) { var elementType = GetElementType(element, treatObjectIdAsKey); var propertyName = GetResourcePropertyName(element, collectionType.ResourceTypeKind); var propertyValue = element.Value; if (string.IsNullOrEmpty(propertyName)) return; var isKey = false; if (IsObjectId(element)) { if (treatObjectIdAsKey) _instanceMetadataCache.AddKeyProperty(collectionType, propertyName, elementType); else _instanceMetadataCache.AddPrimitiveProperty(collectionType, propertyName, elementType); isKey = true; } else if (elementType == typeof(BsonDocument)) { AddDocumentProperty(context, collectionName, collectionType, propertyName, element); } else if (elementType == typeof(BsonArray)) { RegisterArrayProperty(context, collectionType, element); } else { _instanceMetadataCache.AddPrimitiveProperty(collectionType, propertyName, elementType); } if (!string.IsNullOrEmpty(propertyName)) { AddProviderType(collectionName, IsObjectId(element) ? ProviderObjectIdName : propertyName, propertyValue, isKey); } }
private void InsertDocument(MongoContext mongoContext, ResourceChange change) { var collection = mongoContext.Database.GetCollection(change.CollectionName); var document = MongoDSPConverter.CreateBSonDocument(change.Resource, this.mongoMetadata, change.CollectionName); collection.Insert(document); change.Resource.SetValue(MongoMetadata.MappedObjectIdName, document.GetValue(MongoMetadata.ProviderObjectIdName).ToString()); }
internal void UpdateResourceType(MongoContext context, ResourceType resourceType, BsonElement element) { var elementType = GetElementType(element); RegisterResourceProperty(context, resourceType.Name, resourceType, elementType, element, ResourceTypeKind.EntityType); }