Skip to content

Instantly share code, notes, and snippets.

@lauw
Last active April 3, 2022 10:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lauw/20747e47e373444432278985e8eee495 to your computer and use it in GitHub Desktop.
Save lauw/20747e47e373444432278985e8eee495 to your computer and use it in GitHub Desktop.
ReboDb mapping helper to support different casing and default Table/Column attributes
using System.ComponentModel.DataAnnotations.Schema;
namespace UserApi
{
[Table("businesses")]
public class Business
{
[Column("id")]
public int Id { get; set; }
public string Name { get; set; }
public bool Active { get; set; }
}
}
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Reflection;
using RepoDb;
namespace UserApi
{
public enum NameEnclosing
{
None,
Brackets,
DoubleQuotes
}
public enum NameCasing
{
None,
CamelCase,
SnakeCase
}
public class RepoDbMapper
{
public static void MapTablesAndColumns(NameCasing nameCasing = NameCasing.None, NameEnclosing nameEnclosing = NameEnclosing.None)
{
var assembly = Assembly.GetCallingAssembly();
foreach (var type in assembly.GetTypes())
{
var tableAttribute = type.GetCustomAttribute<TableAttribute>();
if (tableAttribute == null) continue;
var tableName = tableAttribute.Name; // we don't change casing for attribute, assume it's filled in correctly by the user
tableName = EncloseString(tableName, nameEnclosing);
var schemaName = tableAttribute.Schema;
schemaName = EncloseString(schemaName, nameEnclosing);
var databaseObjectName = tableName;
if (!string.IsNullOrEmpty(schemaName))
{
databaseObjectName = $"{schemaName}.{tableName}";
}
ClassMapper.Add(type, databaseObjectName, true);
var addMethod = typeof(PropertyMapper).GetMethod("Add", new [] {typeof(string), typeof(string), typeof(bool)});
var addTypedPropertyMethod = addMethod.MakeGenericMethod(type);
foreach (var memberInfo in type.GetProperties())
{
var columnAttribute = memberInfo.GetCustomAttribute<ColumnAttribute>();
var columnName = columnAttribute != null ? columnAttribute.Name : CaseString(memberInfo.Name, nameCasing);
columnName = EncloseString(columnName, nameEnclosing);
addTypedPropertyMethod.Invoke(null, new object[]{ memberInfo.Name, columnName, true });
}
}
}
private static string CaseString(string str, NameCasing nameCasing)
{
if (string.IsNullOrEmpty(str))
return str;
if (nameCasing == NameCasing.CamelCase)
return char.ToLowerInvariant(str[0]) + str.Substring(1);
if (nameCasing == NameCasing.SnakeCase)
return string.Concat(str.Select((c, i) => i > 0 && char.IsUpper(c) ? "_" + c : c.ToString())).ToLower();
return str;
}
private static string EncloseString(string str, NameEnclosing enclosingCharacters)
{
if (string.IsNullOrEmpty(str))
return str;
if (enclosingCharacters == NameEnclosing.Brackets)
return $"[{str}]";
if (enclosingCharacters == NameEnclosing.DoubleQuotes)
return $"\"{str}\"";
return str;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment