using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
namespace PayRollDAL.CustomeCode.Extension
{
public static class DTOMapperExtensions
{
///
/// Populates a DTO from a Dapper dynamic row using optional
/// column-name prefix and/or alias mapping.
///
/// Target DTO instance.
/// Dynamic row cast to object (IDictionary<string,object>).
///
/// Prepended to each property name to build the column alias to look up.
/// e.g. prefix="Perm", property "AddressId" → looks up "PermAddressId".
///
///
/// Optional post-transform applied AFTER prefix is prepended.
/// Receives the already-prefixed alias. Use when the column name
/// doesn't follow a simple prefix pattern.
///
public static T PopulateFromDynamic(
this T dto,
object row,
string prefix = "",
Func aliasMapper = null)
where T : class
{
var dict = (IDictionary)row;
var properties = typeof(T)
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.CanWrite);
foreach (var prop in properties)
{
// Build the column alias: start with prop name, prepend prefix
string dbAlias = string.IsNullOrEmpty(prefix)
? prop.Name
: prefix + prop.Name;
// Optionally transform the alias further
if (aliasMapper != null)
dbAlias = aliasMapper(dbAlias);
if (!dict.TryGetValue(dbAlias, out var value)
|| value == null
|| value == DBNull.Value)
continue;
try
{
var propType = Nullable.GetUnderlyingType(prop.PropertyType)
?? prop.PropertyType;
object convertedValue;
if (propType == typeof(int) && value is long l) convertedValue = (int)l;
else if (propType == typeof(byte) && value is int ib) convertedValue = (byte)ib;
else if (propType == typeof(short) && value is int is_) convertedValue = (short)is_;
else if (propType == typeof(DateTime) && value is DateTime dt) convertedValue = dt;
else if (propType == typeof(string)) convertedValue = value.ToString();
else convertedValue = Convert.ChangeType(value, propType);
prop.SetValue(dto, convertedValue);
}
catch
{
// Skip properties whose DB value cannot be converted
// (e.g. type mismatch on nullable columns)
}
}
return dto;
}
}
}