Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@ private DefaultMappingPack()
{
new CollectionNameProcessor(),
new HierarchyProcessor(),
new PropertyMappingProcessor(),
new EntityIdProcessor(),
new MappedPropertiesProcessor(),
new NestedTypeProcessor(),
new ExtraElementsProcessor(),
new TypeDiscoveryProcessor(),
new BsonKnownTypesProcessor(),
new ClassMapPropertiesProcessor(),
new IndexProcessor(),
new EntityRelationshipProcessor()
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public static IEnumerable<IEntityProperty> TraverseProperties(this IEntityDefini
var propertyType = property.PropertyType;
propertyType = propertyType.GetEnumerableItemTypeOrDefault();

if (propertyType.IsClass && !state.SeenTypes.Contains(propertyType))
if (propertyType.IsClass && propertyType != typeof(string) && !state.SeenTypes.Contains(propertyType))
{
var nestedProperties = EntityMapping.GetOrCreateDefinition(propertyType)
.GetAllProperties()
Expand Down
11 changes: 2 additions & 9 deletions src/MongoFramework/Infrastructure/Mapping/EntityMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,14 @@ public static IEntityDefinition RegisterType(Type entityType)
MappingLock.EnterUpgradeableReadLock();
try
{
//For reasons unknown to me, you can't just call "BsonClassMap.LookupClassMap" as that "freezes" the class map
//Instead, you must do the lookup and initial creation yourself.
var classMap = BsonClassMap.GetRegisteredClassMaps()
.Where(cm => cm.ClassType == entityType).FirstOrDefault();

if (classMap == null)
if (!BsonClassMap.IsClassMapRegistered(entityType))
{
MappingLock.EnterWriteLock();

try
{
classMap = new BsonClassMap(entityType);

var classMap = new BsonClassMap(entityType);
BsonClassMap.RegisterClassMap(classMap);
classMap.AutoMap();

foreach (var processor in MappingProcessors)
{
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,37 @@ public void ApplyMapping(IEntityDefinition definition, BsonClassMap classMap)
var entityType = definition.EntityType;

//Find the first property with the "Key" attribute to use as the Id
var properties = entityType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
var idProperty = properties.Where(p => p.GetCustomAttribute<KeyAttribute>() != null).FirstOrDefault();
if (idProperty != null)
var properties = definition.Properties;
var idProperty = properties.Where(p => p.PropertyInfo.GetCustomAttribute<KeyAttribute>() != null).FirstOrDefault();
if (idProperty == null)
{
classMap.MapIdMember(idProperty);
idProperty = properties
.Where(p => p.ElementName.Equals("id", StringComparison.InvariantCultureIgnoreCase))
.FirstOrDefault();
}

//If there is no Id generator, set a default based on the member type
if (classMap.IdMemberMap != null && classMap.IdMemberMap.IdGenerator == null)
if (idProperty is EntityProperty entityProperty)
{
var idMemberMap = classMap.IdMemberMap;
var memberType = BsonClassMap.GetMemberInfoType(idMemberMap.MemberInfo);
if (memberType == typeof(string))
{
idMemberMap.SetIdGenerator(StringObjectIdGenerator.Instance);
}
else if (memberType == typeof(Guid))
{
idMemberMap.SetIdGenerator(CombGuidGenerator.Instance);
}
else if (memberType == typeof(ObjectId))
classMap.MapIdMember(idProperty.PropertyInfo);
entityProperty.IsKey = true;

//If there is no Id generator, set a default based on the member type
if (classMap.IdMemberMap.IdGenerator == null)
{
idMemberMap.SetIdGenerator(ObjectIdGenerator.Instance);
var idMemberMap = classMap.IdMemberMap;
var memberType = BsonClassMap.GetMemberInfoType(idMemberMap.MemberInfo);
if (memberType == typeof(string))
{
idMemberMap.SetIdGenerator(StringObjectIdGenerator.Instance);
}
else if (memberType == typeof(Guid))
{
idMemberMap.SetIdGenerator(CombGuidGenerator.Instance);
}
else if (memberType == typeof(ObjectId))
{
idMemberMap.SetIdGenerator(ObjectIdGenerator.Instance);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public void ApplyMapping(IEntityDefinition definition, BsonClassMap classMap)
{
definition.Relationships = GetEntityRelationships(definition).ToArray();

var removeProperties = new HashSet<string>();

foreach (var relationship in definition.Relationships)
{
if (relationship.IsCollection)
Expand All @@ -27,9 +29,13 @@ public void ApplyMapping(IEntityDefinition definition, BsonClassMap classMap)
}
else
{
removeProperties.Add(relationship.NavigationProperty.FullPath);
classMap.UnmapMember(relationship.NavigationProperty.PropertyInfo);
}
}

//Remove navigation properties
definition.Properties = definition.Properties.Where(p => !removeProperties.Contains(p.FullPath)).ToArray();
}
private IEnumerable<IEntityRelationship> GetEntityRelationships(IEntityDefinition definition)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,20 @@ public void ApplyMapping(IEntityDefinition definition, BsonClassMap classMap)
}
else
{
classMap.SetIgnoreExtraElements(false);

//If any of the Entity's properties have the "ExtraElementsAttribute", assign that against the BsonClassMap
var extraElementsProperty = entityType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
var extraElementsProperty = definition.Properties
.Select(p => new
{
PropertyInfo = p,
ExtraElementsAttribute = p.GetCustomAttribute<ExtraElementsAttribute>()
Property = p,
ExtraElementsAttribute = p.PropertyInfo.GetCustomAttribute<ExtraElementsAttribute>()
}).Where(p => p.ExtraElementsAttribute != null).FirstOrDefault();

if (extraElementsProperty != null && typeof(IDictionary<string, object>).IsAssignableFrom(extraElementsProperty.PropertyInfo.PropertyType))
if (extraElementsProperty != null && typeof(IDictionary<string, object>).IsAssignableFrom(extraElementsProperty.Property.PropertyType))
{
var memberMap = classMap.DeclaredMemberMaps
.Where(m => m.MemberInfo == extraElementsProperty.PropertyInfo)
.Where(m => m.ElementName == extraElementsProperty.Property.ElementName)
.FirstOrDefault();
classMap.SetExtraElementsMember(memberMap);
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ public class NestedTypeProcessor : IMappingProcessor
public void ApplyMapping(IEntityDefinition definition, BsonClassMap classMap)
{
var entityType = definition.EntityType;
var properties = entityType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
var properties = definition.Properties;

foreach (var property in properties)
{
var propertyType = property.PropertyType;
propertyType = propertyType.GetEnumerableItemTypeOrDefault();

//Maps the property type for handling property nesting
if (propertyType.IsClass && propertyType != entityType)
if (propertyType.IsClass && propertyType != entityType && propertyType != typeof(string))
{
if (!EntityMapping.IsRegistered(propertyType))
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using MongoDB.Bson.Serialization;
using System;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Reflection;

namespace MongoFramework.Infrastructure.Mapping.Processors
{
public class PropertyMappingProcessor : IMappingProcessor
{
public void ApplyMapping(IEntityDefinition definition, BsonClassMap classMap)
{
var entityType = definition.EntityType;
var properties = entityType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);

foreach (var property in properties)
{
if (!property.CanRead || !property.CanWrite)
{
continue;
}

//Skip overridden properties
var getMethod = property.GetMethod;
if (property.GetMethod.IsVirtual && getMethod.GetBaseDefinition().DeclaringType != entityType)
{
continue;
}

//Skip indexer properties (eg. "this[int index]")
if (property.GetIndexParameters().Length > 0)
{
continue;
}

//Skip properties with the "NotMappedAttribute"
var notMappedAttribute = property.GetCustomAttribute<NotMappedAttribute>();
if (notMappedAttribute != null)
{
continue;
}

//Do the mapping
var memberMap = classMap.MapMember(property);

//Set custom element name with the "ColumnAttribute"
var columnAttribute = property.GetCustomAttribute<ColumnAttribute>();
if (columnAttribute != null)
{
var mappedName = columnAttribute.Name;
memberMap.SetElementName(mappedName);
}
}

definition.Properties = classMap.DeclaredMemberMaps
.Select(m => new EntityProperty
{
EntityType = definition.EntityType,
IsKey = m == classMap.IdMemberMap,
ElementName = m.ElementName,
FullPath = m.ElementName,
PropertyType = (m.MemberInfo as PropertyInfo).PropertyType,
PropertyInfo = (m.MemberInfo as PropertyInfo)
}).ToArray();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,4 @@
<ProjectReference Include="..\..\src\MongoFramework\MongoFramework.csproj" />
</ItemGroup>

<ItemGroup>
<Folder Include="docs\" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,16 @@ public class ExplicitKeyOverridesImplicitIdModel
[TestMethod]
public void IdMapsOnAttribute()
{
EntityMapping.AddMappingProcessor(new PropertyMappingProcessor());
EntityMapping.AddMappingProcessor(new EntityIdProcessor());
EntityMapping.AddMappingProcessor(new ClassMapPropertiesProcessor());
var definition = EntityMapping.RegisterType(typeof(IdByAttributeTestModel));
Assert.AreEqual("MyCustomId", definition.GetIdName());
}

[TestMethod]
public void StringIdGeneratorOnStringProperty()
{
EntityMapping.AddMappingProcessor(new PropertyMappingProcessor());
EntityMapping.AddMappingProcessor(new EntityIdProcessor());
EntityMapping.RegisterType(typeof(StringIdGeneratorTestModel));

Expand All @@ -68,6 +69,7 @@ public void StringIdGeneratorOnStringProperty()
[TestMethod]
public void GuidIdGeneratorOnGuidProperty()
{
EntityMapping.AddMappingProcessor(new PropertyMappingProcessor());
EntityMapping.AddMappingProcessor(new EntityIdProcessor());
EntityMapping.RegisterType(typeof(GuidIdGeneratorTestModel));

Expand All @@ -80,6 +82,7 @@ public void GuidIdGeneratorOnGuidProperty()
[TestMethod]
public void ObjectIdGeneratorOnObjectIdProperty()
{
EntityMapping.AddMappingProcessor(new PropertyMappingProcessor());
EntityMapping.AddMappingProcessor(new EntityIdProcessor());
EntityMapping.RegisterType(typeof(ObjectIdGeneratorTestModel));

Expand All @@ -92,6 +95,7 @@ public void ObjectIdGeneratorOnObjectIdProperty()
[TestMethod]
public void ExplicitKeyOverridesImplicitId()
{
EntityMapping.AddMappingProcessor(new PropertyMappingProcessor());
EntityMapping.AddMappingProcessor(new EntityIdProcessor());
EntityMapping.RegisterType(typeof(ExplicitKeyOverridesImplicitIdModel));

Expand Down
Loading