public EntityReader(IMongoDbConnection connection) { Connection = connection ?? throw new ArgumentNullException(nameof(connection)); EntityDefinition = EntityMapping.GetOrCreateDefinition(typeof(TEntity)); }
public EntityIndexWriter(IMongoDbConnection connection) { Connection = connection; EntityDefinition = EntityMapping.GetOrCreateDefinition(typeof(TEntity)); }
public static UpdateDefinition <TEntity> Set <TEntity>(this UpdateDefinition <TEntity> definition, string fieldName, BsonValue value) where TEntity : class { var dotNetValue = BsonTypeMapper.MapToDotNetValue(value); var valueType = dotNetValue?.GetType(); IEntityProperty propertyDefinition = null; if (EntityMapping.IsValidTypeToMap(typeof(TEntity))) { propertyDefinition = EntityMapping.GetOrCreateDefinition(typeof(TEntity)) .TraverseProperties() .Where(p => p.FullPath == fieldName) .FirstOrDefault(); } var propertyType = propertyDefinition?.PropertyType; if (valueType == null && propertyType == null) { //For null values - they don't have any type data associated valueType = typeof(object); } else if (valueType == null || (propertyType != null && valueType != propertyType)) { //Where BsonTypeMapper can't determine the type or it is a mismatch to what is set in the entity definition //The preference is on the definition type and the serializer on the specific member valueType = propertyType; //We will need the serializer defined for the specific member //Not all serializers will be registered (eg. EntityNavigationSerializer) so we need to look it up manually var declaringClassMap = BsonClassMap.LookupClassMap(propertyDefinition.EntityType); var memberMap = declaringClassMap.GetMemberMapForElement(propertyDefinition.ElementName); var serializer = memberMap.GetSerializer(); //To prevent re-serializing back to a string, we use the BsonDocumentReader over JsonReader //Using BsonDocumentReader means the root must be a BsonDocument. Because the value may be a BsonArray, we need to wrap the value. var containerDocument = new BsonDocument { { "Value", value } }; using (var reader = new BsonDocumentReader(containerDocument)) { //Get the reader into a state where the serializer is starting on the right element reader.ReadBsonType(); reader.ReadStartDocument(); reader.ReadBsonType(); reader.SkipName(); var context = BsonDeserializationContext.CreateRoot(reader); dotNetValue = serializer.Deserialize(context); } } var typeArgs = new[] { typeof(TEntity), valueType }; var specificDefinitionType = typeof(StringFieldDefinition <,>).MakeGenericType(typeArgs); var specificDefinition = Activator.CreateInstance(specificDefinitionType, fieldName, null); //ie. StringFieldDefintion<TEntity, valueType> foreach (var method in typeof(UpdateDefinitionExtensions).GetMethods(BindingFlags.NonPublic | BindingFlags.Static)) { if (method.Name == nameof(InternalSet)) { var internalSetMethod = method.MakeGenericMethod(typeArgs); var result = internalSetMethod.Invoke(null, new[] { definition, specificDefinition, dotNetValue }); return(result as UpdateDefinition <TEntity>); } } return(default);
public EntityRelationshipWriter(IMongoDbConnection connection) { Connection = connection; Relationships = EntityMapping.GetOrCreateDefinition(typeof(TEntity)).Relationships; }
public EntityCollection() { EntityDefinition = EntityMapping.GetOrCreateDefinition(typeof(TEntity)); }
public MongoFrameworkQueryProvider(IMongoDbConnection connection, BsonDocument preStage) { Connection = connection; EntityDefinition = EntityMapping.GetOrCreateDefinition(typeof(TEntity)); PreStage = preStage; }
public IEnumerable <WriteModel <TEntity> > GetModel() { var definition = EntityMapping.GetOrCreateDefinition(typeof(TEntity)); yield return(new DeleteOneModel <TEntity>(definition.CreateIdFilter <TEntity>(EntityId))); }
public DeviceMongoContext(IMongoDbConnection Connection) : base(Connection) { EntityMapping.GetOrCreateDefinition(typeof(DeviceView)).CollectionName = "Test.Devices"; EntityMapping.GetOrCreateDefinition(typeof(DeviceReadingModel)).CollectionName = "Test.DeviceReadings"; }
private IEnumerable <IEntityRelationship> GetEntityRelationships(IEntityDefinition definition) { var entityType = definition.EntityType; var propertyMap = definition.GetAllProperties().ToDictionary(p => p.PropertyInfo.Name, p => p); foreach (var mapping in propertyMap) { var currentProperty = mapping.Value; var propertyInfo = currentProperty.PropertyInfo; var propertyType = currentProperty.PropertyType; //For a single entity relationship var foreignKeyAttr = propertyInfo.GetCustomAttribute <ForeignKeyAttribute>(); if (foreignKeyAttr != null) { var linkedProperty = propertyMap.ContainsKey(foreignKeyAttr.Name) ? propertyMap[foreignKeyAttr.Name] : null; if (linkedProperty == null) { throw new InvalidOperationException($"Can't find property {foreignKeyAttr.Name} in {entityType.Name} as indicated by the {nameof(ForeignKeyAttribute)}."); } else if (IdTypes.Contains(currentProperty.PropertyType)) { yield return(new EntityRelationship { IdProperty = currentProperty, NavigationProperty = linkedProperty, EntityType = linkedProperty.PropertyType }); } else if (IdTypes.Contains(linkedProperty.PropertyType)) { yield return(new EntityRelationship { IdProperty = linkedProperty, NavigationProperty = currentProperty, EntityType = currentProperty.PropertyType }); } else { throw new InvalidOperationException($"Unable to determine the Id property between {currentProperty} and {linkedProperty}. Check the types for these properties are valid."); } continue; } //For an entity collection relationship if (propertyInfo.CanRead && propertyInfo.GetGetMethod().IsVirtual&& propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(ICollection <>)) { var collectionEntityType = propertyType.GetGenericArguments().FirstOrDefault(); var inversePropertyAttr = propertyInfo.GetCustomAttribute <InversePropertyAttribute>(); var relatedEntityMapping = EntityMapping.GetOrCreateDefinition(collectionEntityType).GetAllProperties(); IEntityProperty idProperty; if (inversePropertyAttr != null) { idProperty = relatedEntityMapping.Where(p => p.PropertyInfo.Name == inversePropertyAttr.Property).FirstOrDefault(); if (idProperty == null) { throw new InvalidOperationException($"Can't find property {inversePropertyAttr.Property} in {collectionEntityType} as indicated by the InversePropertyAttribute on {currentProperty}"); } else if (!IdTypes.Contains(idProperty.PropertyType)) { throw new InvalidOperationException($"The Id property {inversePropertyAttr.Property} in {collectionEntityType.Name} isn't of a compatible type."); } } else { //Default to the Id when no specific foreign key is found idProperty = relatedEntityMapping.Where(p => p.IsKey).FirstOrDefault(); } yield return(new EntityRelationship { IdProperty = idProperty, NavigationProperty = currentProperty, EntityType = collectionEntityType, IsCollection = true }); } } }