Last active
April 3, 2022 10:39
-
-
Save lauw/20747e47e373444432278985e8eee495 to your computer and use it in GitHub Desktop.
ReboDb mapping helper to support different casing and default Table/Column attributes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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