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));
 }
Exemple #3
0
        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);
Exemple #4
0
 public EntityRelationshipWriter(IMongoDbConnection connection)
 {
     Connection    = connection;
     Relationships = EntityMapping.GetOrCreateDefinition(typeof(TEntity)).Relationships;
 }
Exemple #5
0
 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
                    });
                }
            }
        }