using System;
using System.Reflection;
using Marr.Data.Mapping.Strategies;
using System.Collections;
namespace Marr.Data.Mapping
{
///
/// Provides a fluent interface for mapping domain entities and properties to database tables and columns.
///
public class FluentMappings
{
private bool _publicOnly;
public FluentMappings()
: this(true)
{ }
public FluentMappings(bool publicOnly)
{
_publicOnly = publicOnly;
}
public MappingsFluentEntity Entity()
{
return new MappingsFluentEntity(_publicOnly);
}
public class MappingsFluentEntity
{
public MappingsFluentEntity(bool publicOnly)
{
Columns = new MappingsFluentColumns(this, publicOnly);
Table = new MappingsFluentTables(this);
Relationships = new MappingsFluentRelationships(this, publicOnly);
}
///
/// Contains methods that map entity properties to database table and view column names;
///
public MappingsFluentColumns Columns { get; private set; }
///
/// Contains methods that map entity classes to database table names.
///
public MappingsFluentTables Table { get; private set; }
///
/// Contains methods that map sub-entities with database table and view column names.
///
public MappingsFluentRelationships Relationships { get; private set; }
}
public class MappingsFluentColumns
{
private bool _publicOnly;
private FluentMappings.MappingsFluentEntity _fluentEntity;
public MappingsFluentColumns(FluentMappings.MappingsFluentEntity fluentEntity, bool publicOnly)
{
_fluentEntity = fluentEntity;
_publicOnly = publicOnly;
}
///
/// Creates column mappings for the given type.
/// Maps all properties except ICollection properties.
///
/// The type that is being built.
///
public ColumnMapBuilder AutoMapAllProperties()
{
return AutoMapPropertiesWhere(m => m.MemberType == MemberTypes.Property &&
!typeof(ICollection).IsAssignableFrom((m as PropertyInfo).PropertyType));
}
///
/// Creates column mappings for the given type.
/// Maps all properties that are simple types (int, string, DateTime, etc).
/// ICollection properties are not included.
///
/// The type that is being built.
///
public ColumnMapBuilder AutoMapSimpleTypeProperties()
{
return AutoMapPropertiesWhere(m => m.MemberType == MemberTypes.Property &&
DataHelper.IsSimpleType((m as PropertyInfo).PropertyType) &&
!typeof(ICollection).IsAssignableFrom((m as PropertyInfo).PropertyType));
}
///
/// Creates column mappings for the given type if they match the predicate.
///
/// The type that is being built.
/// Determines whether a mapping should be created based on the member info.
///
public ColumnMapBuilder AutoMapPropertiesWhere(Func predicate)
{
Type entityType = typeof(TEntity);
ConventionMapStrategy strategy = new ConventionMapStrategy(_publicOnly);
strategy.ColumnPredicate = predicate;
ColumnMapCollection columns = strategy.MapColumns(entityType);
MapRepository.Instance.Columns[entityType] = columns;
return new ColumnMapBuilder(_fluentEntity, columns);
}
///
/// Creates a ColumnMapBuilder that starts out with no pre-populated columns.
/// All columns must be added manually using the builder.
///
///
///
public ColumnMapBuilder MapProperties()
{
Type entityType = typeof(TEntity);
ColumnMapCollection columns = new ColumnMapCollection();
MapRepository.Instance.Columns[entityType] = columns;
return new ColumnMapBuilder(_fluentEntity, columns);
}
}
public class MappingsFluentTables
{
private FluentMappings.MappingsFluentEntity _fluentEntity;
public MappingsFluentTables(FluentMappings.MappingsFluentEntity fluentEntity)
{
_fluentEntity = fluentEntity;
}
///
/// Provides a fluent table mapping interface.
///
///
///
public TableBuilder AutoMapTable()
{
return new TableBuilder(_fluentEntity);
}
///
/// Sets the table name for a given type.
///
///
///
public TableBuilder MapTable(string tableName)
{
return new TableBuilder(_fluentEntity).SetTableName(tableName);
}
}
public class MappingsFluentRelationships
{
private FluentMappings.MappingsFluentEntity _fluentEntity;
private bool _publicOnly;
public MappingsFluentRelationships(FluentMappings.MappingsFluentEntity fluentEntity, bool publicOnly)
{
_fluentEntity = fluentEntity;
_publicOnly = publicOnly;
}
///
/// Creates relationship mappings for the given type.
/// Maps all properties that implement ICollection or are not "simple types".
///
///
public RelationshipBuilder AutoMapICollectionOrComplexProperties()
{
return AutoMapPropertiesWhere(m =>
m.MemberType == MemberTypes.Property &&
(
typeof(ICollection).IsAssignableFrom((m as PropertyInfo).PropertyType) || !DataHelper.IsSimpleType((m as PropertyInfo).PropertyType)
)
);
}
///
/// Creates relationship mappings for the given type.
/// Maps all properties that implement ICollection.
///
///
public RelationshipBuilder AutoMapICollectionProperties()
{
return AutoMapPropertiesWhere(m =>
m.MemberType == MemberTypes.Property &&
typeof(ICollection).IsAssignableFrom((m as PropertyInfo).PropertyType));
}
///
/// Creates relationship mappings for the given type.
/// Maps all properties that are not "simple types".
///
///
public RelationshipBuilder AutoMapComplexTypeProperties()
{
return AutoMapPropertiesWhere(m =>
m.MemberType == MemberTypes.Property &&
!DataHelper.IsSimpleType((m as PropertyInfo).PropertyType));
}
///
/// Creates relationship mappings for the given type if they match the predicate.
///
/// Determines whether a mapping should be created based on the member info.
///
public RelationshipBuilder AutoMapPropertiesWhere(Func predicate)
{
Type entityType = typeof(TEntity);
ConventionMapStrategy strategy = new ConventionMapStrategy(_publicOnly);
strategy.RelationshipPredicate = predicate;
RelationshipCollection relationships = strategy.MapRelationships(entityType);
MapRepository.Instance.Relationships[entityType] = relationships;
return new RelationshipBuilder(_fluentEntity, relationships);
}
///
/// Creates a RelationshipBuilder that starts out with no pre-populated relationships.
/// All relationships must be added manually using the builder.
///
///
public RelationshipBuilder MapProperties()
{
Type entityType = typeof(T);
RelationshipCollection relationships = new RelationshipCollection();
MapRepository.Instance.Relationships[entityType] = relationships;
return new RelationshipBuilder(_fluentEntity, relationships);
}
}
}
}