using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Data;
using Marr.Data.Mapping.Strategies;
namespace Marr.Data.Mapping
{
///
/// This class has fluent methods that are used to easily configure column mappings.
///
///
public class ColumnMapBuilder
{
private FluentMappings.MappingsFluentEntity _fluentEntity;
private string _currentPropertyName;
public ColumnMapBuilder(FluentMappings.MappingsFluentEntity fluentEntity, ColumnMapCollection mappedColumns)
{
_fluentEntity = fluentEntity;
MappedColumns = mappedColumns;
}
///
/// Gets the list of column mappings that are being configured.
///
public ColumnMapCollection MappedColumns { get; private set; }
#region - Fluent Methods -
///
/// Initializes the configurator to configure the given property.
///
///
///
public ColumnMapBuilder For(Expression> property)
{
For(property.GetMemberName());
return this;
}
///
/// Initializes the configurator to configure the given property or field.
///
///
///
public ColumnMapBuilder For(string propertyName)
{
_currentPropertyName = propertyName;
// Try to add the column map if it doesn't exist
if (MappedColumns.GetByFieldName(_currentPropertyName) == null)
{
TryAddColumnMapForField(_currentPropertyName);
}
return this;
}
public ColumnMapBuilder SetPrimaryKey()
{
AssertCurrentPropertyIsSet();
return SetPrimaryKey(_currentPropertyName);
}
public ColumnMapBuilder SetPrimaryKey(string propertyName)
{
MappedColumns.GetByFieldName(propertyName).ColumnInfo.IsPrimaryKey = true;
return this;
}
public ColumnMapBuilder SetAutoIncrement()
{
AssertCurrentPropertyIsSet();
return SetAutoIncrement(_currentPropertyName);
}
public ColumnMapBuilder SetAutoIncrement(string propertyName)
{
MappedColumns.GetByFieldName(propertyName).ColumnInfo.IsAutoIncrement = true;
return this;
}
public ColumnMapBuilder SetColumnName(string columnName)
{
AssertCurrentPropertyIsSet();
return SetColumnName(_currentPropertyName, columnName);
}
public ColumnMapBuilder SetColumnName(string propertyName, string columnName)
{
MappedColumns.GetByFieldName(propertyName).ColumnInfo.Name = columnName;
return this;
}
public ColumnMapBuilder SetReturnValue()
{
AssertCurrentPropertyIsSet();
return SetReturnValue(_currentPropertyName);
}
public ColumnMapBuilder SetReturnValue(string propertyName)
{
MappedColumns.GetByFieldName(propertyName).ColumnInfo.ReturnValue = true;
return this;
}
public ColumnMapBuilder SetSize(int size)
{
AssertCurrentPropertyIsSet();
return SetSize(_currentPropertyName, size);
}
public ColumnMapBuilder SetSize(string propertyName, int size)
{
MappedColumns.GetByFieldName(propertyName).ColumnInfo.Size = size;
return this;
}
public ColumnMapBuilder SetAltName(string altName)
{
AssertCurrentPropertyIsSet();
return SetAltName(_currentPropertyName, altName);
}
public ColumnMapBuilder SetAltName(string propertyName, string altName)
{
MappedColumns.GetByFieldName(propertyName).ColumnInfo.AltName = altName;
return this;
}
public ColumnMapBuilder SetParamDirection(ParameterDirection direction)
{
AssertCurrentPropertyIsSet();
return SetParamDirection(_currentPropertyName, direction);
}
public ColumnMapBuilder SetParamDirection(string propertyName, ParameterDirection direction)
{
MappedColumns.GetByFieldName(propertyName).ColumnInfo.ParamDirection = direction;
return this;
}
public ColumnMapBuilder Ignore(Expression> property)
{
string propertyName = property.GetMemberName();
return Ignore(propertyName);
}
public ColumnMapBuilder Ignore(string propertyName)
{
var columnMap = MappedColumns.GetByFieldName(propertyName);
MappedColumns.Remove(columnMap);
return this;
}
public ColumnMapBuilder PrefixAltNames(string prefix)
{
MappedColumns.PrefixAltNames(prefix);
return this;
}
public ColumnMapBuilder SuffixAltNames(string suffix)
{
MappedColumns.SuffixAltNames(suffix);
return this;
}
public FluentMappings.MappingsFluentTables Tables
{
get
{
if (_fluentEntity == null)
{
throw new Exception("This property is not compatible with the obsolete 'MapBuilder' class.");
}
return _fluentEntity.Table;
}
}
public FluentMappings.MappingsFluentRelationships Relationships
{
get
{
if (_fluentEntity == null)
{
throw new Exception("This property is not compatible with the obsolete 'MapBuilder' class.");
}
return _fluentEntity.Relationships;
}
}
public FluentMappings.MappingsFluentEntity Entity()
{
return new FluentMappings.MappingsFluentEntity(true);
}
///
/// Tries to add a ColumnMap for the given field name.
/// Throws and exception if field cannot be found.
///
private void TryAddColumnMapForField(string fieldName)
{
// Set strategy to filter for public or private fields
ConventionMapStrategy strategy = new ConventionMapStrategy(false);
// Find the field that matches the given field name
strategy.ColumnPredicate = mi => mi.Name == fieldName;
ColumnMap columnMap = strategy.MapColumns(typeof(TEntity)).FirstOrDefault();
if (columnMap == null)
{
throw new DataMappingException(string.Format("Could not find the field '{0}' in '{1}'.",
fieldName,
typeof(TEntity).Name));
}
else
{
MappedColumns.Add(columnMap);
}
}
///
/// Throws an exception if the "current" property has not been set.
///
private void AssertCurrentPropertyIsSet()
{
if (string.IsNullOrEmpty(_currentPropertyName))
{
throw new DataMappingException("A property must first be specified using the 'For' method.");
}
}
#endregion
}
}