We have written custom attributes to achieve this. We do mapping-assignment with the help of reflection and here's some sample code for you.
The attribute that is applied to Business object proerties for coloumn-mapping.
/// <summary>
/// Holds mapping information between business objects properties and database table fields.
/// </summary>
[global::System.AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
public sealed class DataFieldMappingAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the DataFieldMappingAttribute class.
/// </summary>
/// <param name="fieldName">Name of the Field in Database Table that the business object properties maps to.</param>
public DataFieldMappingAttribute(string fieldName)
{
this.MappedField = fieldName;
}
/// <summary>
/// Gets or Sets the mapped Database Table Field.
/// </summary>
public string MappedField
{
get;
private set;
}
}
A sample business object would look like this in my application.
User.cs
[TableMapping("Users")]
public class User : EntityBase
{
#region Constructor(s)
public AppUser()
{
BookCollection = new BookCollection();
}
#endregion
#region Properties
#region Default Properties - Direct Field Mapping using DataFieldMappingAttribute
private System.Int32 _UserId;
private System.String _FirstName;
private System.String _LastName;
private System.String _UserName;
private System.Boolean _IsActive;
[DataFieldMapping("UserID")]
[DataObjectFieldAttribute(true, true, false)]
[NotNullOrEmpty(Message = "UserID From Users Table Is Required.")]
public override int Id
{
get
{
return _UserId;
}
set
{
_UserId = value;
}
}
[DataFieldMapping("UserName")]
[Searchable]
[NotNullOrEmpty(Message = "Username Is Required.")]
public string UserName
{
get
{
return _UserName;
}
set
{
_UserName = value;
}
}
[DataFieldMapping("FirstName")]
[Searchable]
public string FirstName
{
get
{
return _FirstName;
}
set
{
_FirstName = value;
}
}
[DataFieldMapping("LastName")]
[Searchable]
public string LastName
{
get
{
return _LastName;
}
set
{
_LastName = value;
}
}
[DataFieldMapping("IsActive")]
public bool IsActive
{
get
{
return _IsActive;
}
set
{
_IsActive = value;
}
}
#region One-To-Many Mappings
public BookCollection Books { get; set; }
#endregion
#region Derived Properties
public string FullName { get { return this.FirstName + " " + this.LastName; } }
#endregion
#endregion
public override bool Validate()
{
bool baseValid = base.Validate();
bool localValid = Books.Validate();
return baseValid && localValid;
}
}
BookCollection.cs
/// <summary>
/// The BookCollection class is designed to work with lists of instances of Book.
/// </summary>
public class BookCollection : EntityCollectionBase<Book>
{
/// <summary>
/// Initializes a new instance of the BookCollection class.
/// </summary>
public BookCollection()
{
}
/// <summary>
/// Initializes a new instance of the BookCollection class.
/// </summary>
public BookCollection (IList<Book> initialList)
: base(initialList)
{
}
}
Here's the DataRow to BusinessObject transacformation method which is wrapped around the call of an Extension method.
/// <summary>
/// Transforms DataRow into business object.
/// </summary>
/// <typeparam name="TEntity">A type that inherits EntityBase.</typeparam>
/// <typeparam name="TDataRow">A type that inherits DataRow.</typeparam>
/// <param name="dataRow">DataRow object which is transformed from business object.</param>
/// <param name="entity">business object which is transformed into DataRow object.</param>
public static void TransformDataRowToEntity<TEntity, TDataRow>(ref TDataRow dataRow, ref TEntity entity)
where TDataRow : DataRow
where TEntity : EntityBase
{
IQueryable<DataField> entityFields = entity.GetDataFields();
foreach (var entityField in entityFields)
{
if (dataRow[entityField.DataFieldMapping.MappedField] is System.DBNull)
{
entityField.Property.SetValue(entity, null, null);
}
else
{
if (entityField.Property.GetType().IsEnum)
{
Type enumType = entityField.Property.GetType();
EnumConverter enumConverter = new EnumConverter(enumType);
object enumValue = enumConverter.ConvertFrom(dataRow[entityField.DataFieldMapping.MappedField]);
entityField.Property.SetValue(entity, enumValue, null);
}
else
{
entityField.Property.SetValue(entity, dataRow[entityField.DataFieldMapping.MappedField], null);
}
}
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…