diff --git a/Dapper.sln b/Dapper.sln index e993c7a4..fa838820 100644 --- a/Dapper.sln +++ b/Dapper.sln @@ -16,8 +16,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution version.json = version.json EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapper.Contrib", "Dapper.Contrib\Dapper.Contrib.csproj", "{4E409F8F-CFBB-4332-8B0A-FD5A283051FD}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapper.Tests.Contrib", "tests\Dapper.Tests.Contrib\Dapper.Tests.Contrib.csproj", "{DAB3C5B7-BCD1-4A5F-BB6B-50D2BB63DB4A}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{4E956F6B-6BD8-46F5-BC85-49292FF8F9AB}" @@ -32,27 +30,29 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{568BD46C tests\docker-compose.yml = tests\docker-compose.yml EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapper.Contrib", "src\Dapper.Contrib\Dapper.Contrib.csproj", "{F36D3111-38BC-488F-BE7F-533B5DC8070A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {4E409F8F-CFBB-4332-8B0A-FD5A283051FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4E409F8F-CFBB-4332-8B0A-FD5A283051FD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4E409F8F-CFBB-4332-8B0A-FD5A283051FD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4E409F8F-CFBB-4332-8B0A-FD5A283051FD}.Release|Any CPU.Build.0 = Release|Any CPU {DAB3C5B7-BCD1-4A5F-BB6B-50D2BB63DB4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {DAB3C5B7-BCD1-4A5F-BB6B-50D2BB63DB4A}.Debug|Any CPU.Build.0 = Debug|Any CPU {DAB3C5B7-BCD1-4A5F-BB6B-50D2BB63DB4A}.Release|Any CPU.ActiveCfg = Release|Any CPU {DAB3C5B7-BCD1-4A5F-BB6B-50D2BB63DB4A}.Release|Any CPU.Build.0 = Release|Any CPU + {F36D3111-38BC-488F-BE7F-533B5DC8070A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F36D3111-38BC-488F-BE7F-533B5DC8070A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F36D3111-38BC-488F-BE7F-533B5DC8070A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F36D3111-38BC-488F-BE7F-533B5DC8070A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {4E409F8F-CFBB-4332-8B0A-FD5A283051FD} = {4E956F6B-6BD8-46F5-BC85-49292FF8F9AB} {DAB3C5B7-BCD1-4A5F-BB6B-50D2BB63DB4A} = {568BD46C-1C65-4D44-870C-12CD72563262} + {F36D3111-38BC-488F-BE7F-533B5DC8070A} = {4E956F6B-6BD8-46F5-BC85-49292FF8F9AB} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {928A4226-96F3-409A-8A83-9E7444488710} diff --git a/Readme.md b/Readme.md index 9a1fd892..b5461da1 100644 --- a/Readme.md +++ b/Readme.md @@ -166,6 +166,18 @@ Dapper.Contrib makes use of some optional attributes: ``` * `[Write(true/false)]` - this property is (not) writeable * `[Computed]` - this property is computed and should not be part of updates +* `[Column("Columnname")]` - this property has a different name in the Database + * Property is called EmployeeId but Column in DB is called employee_id + + ```csharp + public class Employee + { + [ExplicitKey] + [Column("employee_id")] + public Guid EmployeeId { get; set; } + public string Name { get; set; } + } + ``` Limitations and caveats ------- diff --git a/docs/index.md b/docs/index.md index 816b1c8a..18dbfaf0 100644 --- a/docs/index.md +++ b/docs/index.md @@ -16,7 +16,7 @@ Note: to get the latest pre-release build, add ` -Pre` to the end of the command ### Unreleased -(note: new PRs will not be merged until they add release note wording here) +* Added Column Attribute for different column name to property name ### Previous Releases diff --git a/src/Dapper.Contrib/Dapper.Contrib.csproj b/src/Dapper.Contrib/Dapper.Contrib.csproj index 86a0cbb2..76c10ffa 100644 --- a/src/Dapper.Contrib/Dapper.Contrib.csproj +++ b/src/Dapper.Contrib/Dapper.Contrib.csproj @@ -8,6 +8,11 @@ net461;netstandard2.0;net5.0 false $(NoWarn);CA1050 + true + Dapper.Contrib.WithColumn + 1.0.3 + https://github.com/Tiefseetauchner/Dapper.Contrib + https://github.com/Tiefseetauchner/Dapper.Contrib @@ -19,4 +24,4 @@ - \ No newline at end of file + diff --git a/src/Dapper.Contrib/SqlMapperExtensions.Async.cs b/src/Dapper.Contrib/SqlMapperExtensions.Async.cs index c93e39a4..6f19afa8 100644 --- a/src/Dapper.Contrib/SqlMapperExtensions.Async.cs +++ b/src/Dapper.Contrib/SqlMapperExtensions.Async.cs @@ -6,6 +6,7 @@ using System.Text; using System.Threading.Tasks; using Dapper; +using Dapper.Contrib.Extensions; namespace Dapper.Contrib.Extensions { @@ -29,8 +30,31 @@ public static async Task GetAsync(this IDbConnection connection, dynamic i { var key = GetSingleKey(nameof(GetAsync)); var name = GetTableName(type); + + var sb = new StringBuilder(); - sql = $"SELECT * FROM {name} WHERE {key.Name} = @id"; + var allProperties = TypePropertiesCache(type); + + var adapter = GetFormatter(connection); + + for (var i = 0; i < allProperties.Count; i++) + { + var property = allProperties[i]; + + if (HasColumnName(property)) + { + adapter.AppendColumnNameAsPropertyName(sb, GetColumnName(property), property.Name); + } + else + { + adapter.AppendColumnName(sb, GetColumnName(property)); + } + + if (i < allProperties.Count - 1) + sb.Append(", "); + } + + sql = $"SELECT {sb} FROM {name} WHERE {GetColumnName(key)} = @id"; GetQueries[type.TypeHandle] = sql; } @@ -88,7 +112,30 @@ public static Task> GetAllAsync(this IDbConnection connection, GetSingleKey(nameof(GetAll)); var name = GetTableName(type); - sql = "SELECT * FROM " + name; + var sb = new StringBuilder(); + + var allProperties = TypePropertiesCache(type); + + var adapter = GetFormatter(connection); + + for (var i = 0; i < allProperties.Count; i++) + { + var property = allProperties[i]; + + if (HasColumnName(property)) + { + adapter.AppendColumnNameAsPropertyName(sb, GetColumnName(property), property.Name); + } + else + { + adapter.AppendColumnName(sb, GetColumnName(property)); + } + + if (i < allProperties.Count - 1) + sb.Append(", "); + } + + sql = $"SELECT {sb} FROM {name}"; GetQueries[cacheType.TypeHandle] = sql; } @@ -107,7 +154,7 @@ private static async Task> GetAllAsyncImpl(IDbConnection conne { var obj = ProxyGenerator.GetInterfaceProxy(); foreach (var property in TypePropertiesCache(type)) - { + { var val = res[property.Name]; if (val == null) continue; if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) @@ -172,7 +219,8 @@ public static Task InsertAsync(this IDbConnection connection, T entityTo for (var i = 0; i < allPropertiesExceptKeyAndComputed.Count; i++) { var property = allPropertiesExceptKeyAndComputed[i]; - sqlAdapter.AppendColumnName(sbColumnList, property.Name); + + sqlAdapter.AppendColumnName(sbColumnList, GetColumnName(property)); if (i < allPropertiesExceptKeyAndComputed.Count - 1) sbColumnList.Append(", "); } @@ -181,6 +229,7 @@ public static Task InsertAsync(this IDbConnection connection, T entityTo for (var i = 0; i < allPropertiesExceptKeyAndComputed.Count; i++) { var property = allPropertiesExceptKeyAndComputed[i]; + sbParameterList.AppendFormat("@{0}", property.Name); if (i < allPropertiesExceptKeyAndComputed.Count - 1) sbParameterList.Append(", "); @@ -252,7 +301,8 @@ public static async Task UpdateAsync(this IDbConnection connection, T e for (var i = 0; i < nonIdProps.Count; i++) { var property = nonIdProps[i]; - adapter.AppendColumnNameEqualsValue(sb, property.Name); + + adapter.AppendColumnNameEqualsValue(sb, GetColumnName(property), property.Name); if (i < nonIdProps.Count - 1) sb.Append(", "); } @@ -260,7 +310,10 @@ public static async Task UpdateAsync(this IDbConnection connection, T e for (var i = 0; i < keyProperties.Count; i++) { var property = keyProperties[i]; - adapter.AppendColumnNameEqualsValue(sb, property.Name); + + var columnAttribute = property.GetCustomAttribute(); + + adapter.AppendColumnNameEqualsValue(sb, GetColumnName(property), property.Name); if (i < keyProperties.Count - 1) sb.Append(" and "); } @@ -317,7 +370,10 @@ public static async Task DeleteAsync(this IDbConnection connection, T e for (var i = 0; i < allKeyProperties.Count; i++) { var property = allKeyProperties[i]; - adapter.AppendColumnNameEqualsValue(sb, property.Name); + + var columnAttribute = property.GetCustomAttribute(); + + adapter.AppendColumnNameEqualsValue(sb, GetColumnName(property), property.Name); if (i < allKeyProperties.Count - 1) sb.Append(" AND "); } @@ -493,7 +549,8 @@ public async Task InsertAsync(IDbConnection connection, IDbTransaction tran if (!first) sb.Append(", "); first = false; - sb.Append(property.Name); + + sb.Append(GetColumnName(property)); } } @@ -510,6 +567,7 @@ public async Task InsertAsync(IDbConnection connection, IDbTransaction tran } return id; } + private static string GetColumnName(PropertyInfo property) => property.GetCustomAttribute() == null ? property.Name : property.GetCustomAttribute().Name; } public partial class SQLiteAdapter diff --git a/src/Dapper.Contrib/SqlMapperExtensions.cs b/src/Dapper.Contrib/SqlMapperExtensions.cs index 9a30e805..2efef3b2 100644 --- a/src/Dapper.Contrib/SqlMapperExtensions.cs +++ b/src/Dapper.Contrib/SqlMapperExtensions.cs @@ -9,6 +9,7 @@ using System.Threading; using Dapper; +using Dapper.Contrib.Extensions; namespace Dapper.Contrib.Extensions { @@ -176,7 +177,31 @@ public static T Get(this IDbConnection connection, dynamic id, IDbTransaction var key = GetSingleKey(nameof(Get)); var name = GetTableName(type); - sql = $"select * from {name} where {key.Name} = @id"; + var sb = new StringBuilder(); + + var allProperties = TypePropertiesCache(type); + + var adapter = GetFormatter(connection); + + for (var i = 0; i < allProperties.Count; i++) + { + var property = allProperties[i]; + + if (HasColumnName(property)) + { + adapter.AppendColumnNameAsPropertyName(sb, GetColumnName(property), property.Name); + } + else + { + adapter.AppendColumnName(sb, GetColumnName(property)); + } + + if (i < allProperties.Count - 1) + sb.Append(", "); + } + + + sql = $"select {sb} from {name} where {GetColumnName(key)} = @id"; GetQueries[type.TypeHandle] = sql; } @@ -196,6 +221,8 @@ public static T Get(this IDbConnection connection, dynamic id, IDbTransaction foreach (var property in TypePropertiesCache(type)) { + + var val = res[property.Name]; if (val == null) continue; if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) @@ -238,8 +265,30 @@ public static IEnumerable GetAll(this IDbConnection connection, IDbTransac { GetSingleKey(nameof(GetAll)); var name = GetTableName(type); + +var sb = new StringBuilder(); + + var allProperties = TypePropertiesCache(type); + + var adapter = GetFormatter(connection); + + for (var i = 0; i < allProperties.Count; i++) + { + var property = allProperties[i]; - sql = "select * from " + name; + if (HasColumnName(property)) + { + adapter.AppendColumnNameAsPropertyName(sb, GetColumnName(property), property.Name); + } + else + { + adapter.AppendColumnName(sb, GetColumnName(property)); + } + + if (i < allProperties.Count - 1) + sb.Append(", "); + } + sql = $"select {sb} from {name}"; GetQueries[cacheType.TypeHandle] = sql; } @@ -354,7 +403,9 @@ public static long Insert(this IDbConnection connection, T entityToInsert, ID for (var i = 0; i < allPropertiesExceptKeyAndComputed.Count; i++) { var property = allPropertiesExceptKeyAndComputed[i]; - adapter.AppendColumnName(sbColumnList, property.Name); //fix for issue #336 + + adapter.AppendColumnName(sbColumnList, GetColumnName(property)); + if (i < allPropertiesExceptKeyAndComputed.Count - 1) sbColumnList.Append(", "); } @@ -363,6 +414,7 @@ public static long Insert(this IDbConnection connection, T entityToInsert, ID for (var i = 0; i < allPropertiesExceptKeyAndComputed.Count; i++) { var property = allPropertiesExceptKeyAndComputed[i]; + sbParameterList.AppendFormat("@{0}", property.Name); if (i < allPropertiesExceptKeyAndComputed.Count - 1) sbParameterList.Append(", "); @@ -386,7 +438,7 @@ public static long Insert(this IDbConnection connection, T entityToInsert, ID if (wasClosed) connection.Close(); return returnVal; } - + /// /// Updates entity in table "Ts", checks if the entity is modified if the entity is tracked by the Get() extension. /// @@ -442,7 +494,8 @@ public static bool Update(this IDbConnection connection, T entityToUpdate, ID for (var i = 0; i < nonIdProps.Count; i++) { var property = nonIdProps[i]; - adapter.AppendColumnNameEqualsValue(sb, property.Name); //fix for issue #336 + + adapter.AppendColumnNameEqualsValue(sb, GetColumnName(property), property.Name); if (i < nonIdProps.Count - 1) sb.Append(", "); } @@ -450,7 +503,8 @@ public static bool Update(this IDbConnection connection, T entityToUpdate, ID for (var i = 0; i < keyProperties.Count; i++) { var property = keyProperties[i]; - adapter.AppendColumnNameEqualsValue(sb, property.Name); //fix for issue #336 + + adapter.AppendColumnNameEqualsValue(sb, GetColumnName(property), property.Name); //fix for issue #336 if (i < keyProperties.Count - 1) sb.Append(" and "); } @@ -507,7 +561,9 @@ public static bool Delete(this IDbConnection connection, T entityToDelete, ID for (var i = 0; i < keyProperties.Count; i++) { var property = keyProperties[i]; - adapter.AppendColumnNameEqualsValue(sb, property.Name); //fix for issue #336 + + + adapter.AppendColumnNameEqualsValue(sb, GetColumnName(property), property.Name); //fix for issue #336 if (i < keyProperties.Count - 1) sb.Append(" and "); } @@ -588,7 +644,8 @@ public static T GetInterfaceProxy() foreach (var property in typeof(T).GetProperties()) { var isId = property.GetCustomAttributes(true).Any(a => a is KeyAttribute); - CreateProperty(typeBuilder, property.Name, property.PropertyType, setIsDirtyMethod, isId); + + CreateProperty(typeBuilder, GetColumnName(property), property.PropertyType, setIsDirtyMethod, isId); } #if NETSTANDARD2_0 @@ -698,6 +755,12 @@ private static void CreateProperty(TypeBuilder typeBuilder, string propertyNa typeBuilder.DefineMethodOverride(currSetPropMthdBldr, setMethod); } } + + /// + /// Returns the Column name using the column attribute + /// + private static string GetColumnName(PropertyInfo property) => property.GetCustomAttribute() == null ? property.Name : property.GetCustomAttribute().Name; + private static bool HasColumnName(PropertyInfo property) => property.GetCustomAttribute() != null; } /// @@ -721,6 +784,27 @@ public TableAttribute(string tableName) public string Name { get; set; } } + /// + /// Defines the name of a column to use in Dapper.Contrib commands. + /// + [AttributeUsage(AttributeTargets.Property)] + public class ColumnAttribute : Attribute + { + /// + /// Creates a table mapping to a specific name for Dapper.Contrib commands + /// + /// The name of this table in the database. + public ColumnAttribute(string columnName) + { + Name = columnName; + } + + /// + /// The name of the column in the database + /// + public string Name { get; set; } + } + /// /// Specifies that this field is a primary key in the database /// @@ -798,7 +882,15 @@ public partial interface ISqlAdapter /// /// The string builder to append to. /// The column name. - void AppendColumnNameEqualsValue(StringBuilder sb, string columnName); + /// The Properties Name + void AppendColumnNameEqualsValue(StringBuilder sb, string columnName, string propertyName); + /// + /// Adds a column aliased as property to a parameter. + /// + /// The string builder to append to. + /// The column name. + /// The Properties Name + void AppendColumnNameAsPropertyName(StringBuilder sb, string columnName, string propertyName); } /// @@ -851,9 +943,21 @@ public void AppendColumnName(StringBuilder sb, string columnName) /// /// The string builder to append to. /// The column name. - public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName) + /// The Properties Name + public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName, string propertyName) + { + sb.AppendFormat("[{0}] = @{1}", columnName, propertyName); + } + + /// + /// Adds a column aliased as property to a parameter. + /// + /// The string builder to append to. + /// The column name. + /// The Properties Name + public void AppendColumnNameAsPropertyName(StringBuilder sb, string columnName, string propertyName) { - sb.AppendFormat("[{0}] = @{1}", columnName, columnName); + sb.AppendFormat("{0} as {1}", columnName, propertyName); } } @@ -907,9 +1011,21 @@ public void AppendColumnName(StringBuilder sb, string columnName) /// /// The string builder to append to. /// The column name. - public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName) + /// The Properties Name + public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName, string propertyName) { - sb.AppendFormat("[{0}] = @{1}", columnName, columnName); + sb.AppendFormat("[{0}] = @{1}", columnName, propertyName); + } + + /// + /// Adds a column aliased as property to a parameter. + /// + /// The string builder to append to. + /// The column name. + /// The Properties Name + public void AppendColumnNameAsPropertyName(StringBuilder sb, string columnName, string propertyName) + { + sb.AppendFormat("{0} as {1}", columnName, propertyName); } } @@ -962,9 +1078,21 @@ public void AppendColumnName(StringBuilder sb, string columnName) /// /// The string builder to append to. /// The column name. - public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName) + /// The Properties Name + public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName, string propertyName) { - sb.AppendFormat("`{0}` = @{1}", columnName, columnName); + sb.AppendFormat("`{0}` = @{1}", columnName, propertyName); + } + + /// + /// Adds a column aliased as property to a parameter. + /// + /// The string builder to append to. + /// The column name. + /// The Properties Name + public void AppendColumnNameAsPropertyName(StringBuilder sb, string columnName, string propertyName) + { + sb.AppendFormat("{0} as {1}", columnName, propertyName); } } @@ -1005,7 +1133,8 @@ public int Insert(IDbConnection connection, IDbTransaction transaction, int? com if (!first) sb.Append(", "); first = false; - sb.Append(property.Name); + + sb.Append(GetColumnName(property)); } } @@ -1038,9 +1167,21 @@ public void AppendColumnName(StringBuilder sb, string columnName) /// /// The string builder to append to. /// The column name. - public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName) + /// The Properties Name + public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName, string propertyName) + { + sb.AppendFormat("\"{0}\" = @{1}", columnName, propertyName); + } + + /// + /// Adds a column aliased as property to a parameter. + /// + /// The string builder to append to. + /// The column name. + /// The Properties Name + public void AppendColumnNameAsPropertyName(StringBuilder sb, string columnName, string propertyName) { - sb.AppendFormat("\"{0}\" = @{1}", columnName, columnName); + sb.AppendFormat("{0} as {1}", columnName, propertyName); } } @@ -1091,9 +1232,21 @@ public void AppendColumnName(StringBuilder sb, string columnName) /// /// The string builder to append to. /// The column name. - public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName) + /// The Properties Name + public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName, string propertyName) + { + sb.AppendFormat("\"{0}\" = @{1}", columnName, propertyName); + } + + /// + /// Adds a column aliased as property to a parameter. + /// + /// The string builder to append to. + /// The column name. + /// The Properties Name + public void AppendColumnNameAsPropertyName(StringBuilder sb, string columnName, string propertyName) { - sb.AppendFormat("\"{0}\" = @{1}", columnName, columnName); + sb.AppendFormat("{0} as {1}", columnName, propertyName); } } @@ -1148,8 +1301,20 @@ public void AppendColumnName(StringBuilder sb, string columnName) /// /// The string builder to append to. /// The column name. - public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName) + /// The Properties Name + public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName, string propertyName) + { + sb.AppendFormat("{0} = @{1}", columnName, propertyName); + } + + /// + /// Adds a column aliased as property to a parameter. + /// + /// The string builder to append to. + /// The column name. + /// The Properties Name + public void AppendColumnNameAsPropertyName(StringBuilder sb, string columnName, string propertyName) { - sb.AppendFormat("{0} = @{1}", columnName, columnName); + sb.AppendFormat("{0} as {1}", columnName, propertyName); } }