From 21582dd6634e4f12e4688104e0badf60ef95ac56 Mon Sep 17 00:00:00 2001 From: "lena.tauchner" Date: Tue, 1 Feb 2022 18:31:45 +0100 Subject: [PATCH 1/8] Added Column Attribute --- Readme.md | 12 ++++++++ src/Dapper.Contrib/SqlMapperExtensions.cs | 34 ++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) 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/src/Dapper.Contrib/SqlMapperExtensions.cs b/src/Dapper.Contrib/SqlMapperExtensions.cs index 9a30e805..3f500d4f 100644 --- a/src/Dapper.Contrib/SqlMapperExtensions.cs +++ b/src/Dapper.Contrib/SqlMapperExtensions.cs @@ -354,7 +354,18 @@ 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 + + var columnAttribute = property.GetCustomAttribute(); + + if (columnAttribute == null) + { + adapter.AppendColumnName(sbColumnList, property.Name); //fix for issue #336 + } + else + { + adapter.AppendColumnName(sbColumnList, columnAttribute.Name); + } + if (i < allPropertiesExceptKeyAndComputed.Count - 1) sbColumnList.Append(", "); } @@ -721,6 +732,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 /// From f6d271f0603fcf6871e75db223d216301b45138a Mon Sep 17 00:00:00 2001 From: "lena.tauchner" Date: Wed, 2 Feb 2022 00:28:25 +0100 Subject: [PATCH 2/8] Replaced all occurences of property.Name to finish implementation of Attribute --- Dapper.sln | 14 +++--- .../SqlMapperExtensions.Async.cs | 41 ++++++++++++---- src/Dapper.Contrib/SqlMapperExtensions.cs | 48 ++++++++++++------- 3 files changed, 71 insertions(+), 32 deletions(-) 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/src/Dapper.Contrib/SqlMapperExtensions.Async.cs b/src/Dapper.Contrib/SqlMapperExtensions.Async.cs index c93e39a4..bf56eb0d 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 { @@ -49,7 +50,9 @@ public static async Task GetAsync(this IDbConnection connection, dynamic i foreach (var property in TypePropertiesCache(type)) { - var val = res[property.Name]; + var columnAttribute = property.GetCustomAttribute(); + + var val = res[columnAttribute == null ? property.Name : columnAttribute.Name]; if (val == null) continue; if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) { @@ -107,8 +110,10 @@ private static async Task> GetAllAsyncImpl(IDbConnection conne { var obj = ProxyGenerator.GetInterfaceProxy(); foreach (var property in TypePropertiesCache(type)) - { - var val = res[property.Name]; + { + var columnAttribute = property.GetCustomAttribute(); + + var val = res[columnAttribute == null ? property.Name : columnAttribute.Name]; if (val == null) continue; if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) { @@ -172,7 +177,10 @@ 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); + + var columnAttribute = property.GetCustomAttribute(); + + sqlAdapter.AppendColumnName(sbColumnList, columnAttribute == null ? property.Name : columnAttribute.Name); if (i < allPropertiesExceptKeyAndComputed.Count - 1) sbColumnList.Append(", "); } @@ -181,7 +189,10 @@ 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); + + var columnAttribute = property.GetCustomAttribute(); + + sbParameterList.AppendFormat("@{0}", columnAttribute == null ? property.Name : columnAttribute.Name); if (i < allPropertiesExceptKeyAndComputed.Count - 1) sbParameterList.Append(", "); } @@ -252,7 +263,10 @@ 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); + + var columnAttribute = property.GetCustomAttribute(); + + adapter.AppendColumnNameEqualsValue(sb, columnAttribute == null ? property.Name : columnAttribute.Name); if (i < nonIdProps.Count - 1) sb.Append(", "); } @@ -260,7 +274,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, columnAttribute == null ? property.Name : columnAttribute.Name); if (i < keyProperties.Count - 1) sb.Append(" and "); } @@ -317,7 +334,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, columnAttribute == null ? property.Name : columnAttribute.Name); if (i < allKeyProperties.Count - 1) sb.Append(" AND "); } @@ -493,7 +513,10 @@ public async Task InsertAsync(IDbConnection connection, IDbTransaction tran if (!first) sb.Append(", "); first = false; - sb.Append(property.Name); + + var columnAttribute = property.GetCustomAttribute(); + + sb.Append(columnAttribute == null ? property.Name : columnAttribute.Name); } } diff --git a/src/Dapper.Contrib/SqlMapperExtensions.cs b/src/Dapper.Contrib/SqlMapperExtensions.cs index 3f500d4f..b8f04480 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 { @@ -196,7 +197,10 @@ public static T Get(this IDbConnection connection, dynamic id, IDbTransaction foreach (var property in TypePropertiesCache(type)) { - var val = res[property.Name]; + + var columnAttribute = property.GetCustomAttribute(); + + var val = res[columnAttribute == null ? property.Name : columnAttribute.Name]; if (val == null) continue; if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) { @@ -252,7 +256,9 @@ public static IEnumerable GetAll(this IDbConnection connection, IDbTransac var obj = ProxyGenerator.GetInterfaceProxy(); foreach (var property in TypePropertiesCache(type)) { - var val = res[property.Name]; + var columnAttribute = property.GetCustomAttribute(); + + var val = res[columnAttribute == null ? property.Name : columnAttribute.Name]; if (val == null) continue; if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) { @@ -357,14 +363,7 @@ public static long Insert(this IDbConnection connection, T entityToInsert, ID var columnAttribute = property.GetCustomAttribute(); - if (columnAttribute == null) - { - adapter.AppendColumnName(sbColumnList, property.Name); //fix for issue #336 - } - else - { - adapter.AppendColumnName(sbColumnList, columnAttribute.Name); - } + adapter.AppendColumnName(sbColumnList, columnAttribute == null ? property.Name : columnAttribute.Name); if (i < allPropertiesExceptKeyAndComputed.Count - 1) sbColumnList.Append(", "); @@ -374,7 +373,10 @@ 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); + + var columnAttribute = property.GetCustomAttribute(); + + sbParameterList.AppendFormat("@{0}", columnAttribute == null ? property.Name : columnAttribute.Name); if (i < allPropertiesExceptKeyAndComputed.Count - 1) sbParameterList.Append(", "); } @@ -453,7 +455,9 @@ 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 + var columnAttribute = property.GetCustomAttribute(); + + adapter.AppendColumnNameEqualsValue(sb, columnAttribute == null ? property.Name : columnAttribute.Name); if (i < nonIdProps.Count - 1) sb.Append(", "); } @@ -461,7 +465,10 @@ 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 + + var columnAttribute = property.GetCustomAttribute(); + + adapter.AppendColumnNameEqualsValue(sb, columnAttribute == null ? property.Name : columnAttribute.Name); //fix for issue #336 if (i < keyProperties.Count - 1) sb.Append(" and "); } @@ -518,7 +525,10 @@ 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 + + var columnAttribute = property.GetCustomAttribute(); + + adapter.AppendColumnNameEqualsValue(sb, columnAttribute == null ? property.Name : columnAttribute.Name); //fix for issue #336 if (i < keyProperties.Count - 1) sb.Append(" and "); } @@ -599,7 +609,10 @@ 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); + + var columnAttribute = property.GetCustomAttribute(); + + CreateProperty(typeBuilder, columnAttribute == null ? property.Name : columnAttribute.Name, property.PropertyType, setIsDirtyMethod, isId); } #if NETSTANDARD2_0 @@ -1037,7 +1050,10 @@ public int Insert(IDbConnection connection, IDbTransaction transaction, int? com if (!first) sb.Append(", "); first = false; - sb.Append(property.Name); + + var columnAttribute = property.GetCustomAttribute(); + + sb.Append(columnAttribute == null ? property.Name : columnAttribute.Name); } } From ffb4c61a77cacb0f18bc47489c352ad32f54641c Mon Sep 17 00:00:00 2001 From: Nick Craver Date: Sat, 8 May 2021 23:18:44 +0200 Subject: [PATCH 3/8] Added Changelog --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 6e328c6c0c9df528a1a81e8f3b75b2690ea7248d Mon Sep 17 00:00:00 2001 From: "lena.tauchner" Date: Wed, 2 Feb 2022 10:50:00 +0100 Subject: [PATCH 4/8] Fixed Inserts and Updates to use the property name when required (copy pasta issue) --- .../SqlMapperExtensions.Async.cs | 10 ++--- src/Dapper.Contrib/SqlMapperExtensions.cs | 43 +++++++++++-------- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/Dapper.Contrib/SqlMapperExtensions.Async.cs b/src/Dapper.Contrib/SqlMapperExtensions.Async.cs index bf56eb0d..568aa0e6 100644 --- a/src/Dapper.Contrib/SqlMapperExtensions.Async.cs +++ b/src/Dapper.Contrib/SqlMapperExtensions.Async.cs @@ -190,9 +190,7 @@ public static Task InsertAsync(this IDbConnection connection, T entityTo { var property = allPropertiesExceptKeyAndComputed[i]; - var columnAttribute = property.GetCustomAttribute(); - - sbParameterList.AppendFormat("@{0}", columnAttribute == null ? property.Name : columnAttribute.Name); + sbParameterList.AppendFormat("@{0}", property.Name); if (i < allPropertiesExceptKeyAndComputed.Count - 1) sbParameterList.Append(", "); } @@ -266,7 +264,7 @@ public static async Task UpdateAsync(this IDbConnection connection, T e var columnAttribute = property.GetCustomAttribute(); - adapter.AppendColumnNameEqualsValue(sb, columnAttribute == null ? property.Name : columnAttribute.Name); + adapter.AppendColumnNameEqualsValue(sb, columnAttribute == null ? property.Name : columnAttribute.Name, property.Name); if (i < nonIdProps.Count - 1) sb.Append(", "); } @@ -277,7 +275,7 @@ public static async Task UpdateAsync(this IDbConnection connection, T e var columnAttribute = property.GetCustomAttribute(); - adapter.AppendColumnNameEqualsValue(sb, columnAttribute == null ? property.Name : columnAttribute.Name); + adapter.AppendColumnNameEqualsValue(sb, columnAttribute == null ? property.Name : columnAttribute.Name, property.Name); if (i < keyProperties.Count - 1) sb.Append(" and "); } @@ -337,7 +335,7 @@ public static async Task DeleteAsync(this IDbConnection connection, T e var columnAttribute = property.GetCustomAttribute(); - adapter.AppendColumnNameEqualsValue(sb, columnAttribute == null ? property.Name : columnAttribute.Name); + adapter.AppendColumnNameEqualsValue(sb, columnAttribute == null ? property.Name : columnAttribute.Name, property.Name); if (i < allKeyProperties.Count - 1) sb.Append(" AND "); } diff --git a/src/Dapper.Contrib/SqlMapperExtensions.cs b/src/Dapper.Contrib/SqlMapperExtensions.cs index b8f04480..a7ec994f 100644 --- a/src/Dapper.Contrib/SqlMapperExtensions.cs +++ b/src/Dapper.Contrib/SqlMapperExtensions.cs @@ -374,9 +374,7 @@ public static long Insert(this IDbConnection connection, T entityToInsert, ID { var property = allPropertiesExceptKeyAndComputed[i]; - var columnAttribute = property.GetCustomAttribute(); - - sbParameterList.AppendFormat("@{0}", columnAttribute == null ? property.Name : columnAttribute.Name); + sbParameterList.AppendFormat("@{0}", property.Name); if (i < allPropertiesExceptKeyAndComputed.Count - 1) sbParameterList.Append(", "); } @@ -457,7 +455,7 @@ public static bool Update(this IDbConnection connection, T entityToUpdate, ID var property = nonIdProps[i]; var columnAttribute = property.GetCustomAttribute(); - adapter.AppendColumnNameEqualsValue(sb, columnAttribute == null ? property.Name : columnAttribute.Name); + adapter.AppendColumnNameEqualsValue(sb, columnAttribute == null ? property.Name : columnAttribute.Name, property.Name); if (i < nonIdProps.Count - 1) sb.Append(", "); } @@ -468,7 +466,7 @@ public static bool Update(this IDbConnection connection, T entityToUpdate, ID var columnAttribute = property.GetCustomAttribute(); - adapter.AppendColumnNameEqualsValue(sb, columnAttribute == null ? property.Name : columnAttribute.Name); //fix for issue #336 + adapter.AppendColumnNameEqualsValue(sb, columnAttribute == null ? property.Name : columnAttribute.Name, property.Name); //fix for issue #336 if (i < keyProperties.Count - 1) sb.Append(" and "); } @@ -528,7 +526,7 @@ public static bool Delete(this IDbConnection connection, T entityToDelete, ID var columnAttribute = property.GetCustomAttribute(); - adapter.AppendColumnNameEqualsValue(sb, columnAttribute == null ? property.Name : columnAttribute.Name); //fix for issue #336 + adapter.AppendColumnNameEqualsValue(sb, columnAttribute == null ? property.Name : columnAttribute.Name, property.Name); //fix for issue #336 if (i < keyProperties.Count - 1) sb.Append(" and "); } @@ -843,7 +841,8 @@ 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); } /// @@ -896,9 +895,10 @@ 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); } } @@ -952,9 +952,10 @@ 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); } } @@ -1007,9 +1008,10 @@ 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); } } @@ -1086,9 +1088,10 @@ 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); } } @@ -1139,9 +1142,10 @@ 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); } } @@ -1196,8 +1200,9 @@ 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); } } From 948f9bdafc1326235e21936c0f11e774154bd2e7 Mon Sep 17 00:00:00 2001 From: "lena.tauchner" Date: Wed, 2 Feb 2022 12:08:45 +0100 Subject: [PATCH 5/8] Added attribute usage to GET functions --- src/Dapper.Contrib/SqlMapperExtensions.Async.cs | 3 ++- src/Dapper.Contrib/SqlMapperExtensions.cs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Dapper.Contrib/SqlMapperExtensions.Async.cs b/src/Dapper.Contrib/SqlMapperExtensions.Async.cs index 568aa0e6..a60e4cb1 100644 --- a/src/Dapper.Contrib/SqlMapperExtensions.Async.cs +++ b/src/Dapper.Contrib/SqlMapperExtensions.Async.cs @@ -29,9 +29,10 @@ public static async Task GetAsync(this IDbConnection connection, dynamic i if (!GetQueries.TryGetValue(type.TypeHandle, out string sql)) { var key = GetSingleKey(nameof(GetAsync)); + var columnAttribute = key.GetCustomAttribute(); var name = GetTableName(type); - sql = $"SELECT * FROM {name} WHERE {key.Name} = @id"; + sql = $"SELECT * FROM {name} WHERE {(columnAttribute == null ? key.Name : columnAttribute.Name)} = @id"; GetQueries[type.TypeHandle] = sql; } diff --git a/src/Dapper.Contrib/SqlMapperExtensions.cs b/src/Dapper.Contrib/SqlMapperExtensions.cs index a7ec994f..fb6b7887 100644 --- a/src/Dapper.Contrib/SqlMapperExtensions.cs +++ b/src/Dapper.Contrib/SqlMapperExtensions.cs @@ -175,9 +175,10 @@ public static T Get(this IDbConnection connection, dynamic id, IDbTransaction if (!GetQueries.TryGetValue(type.TypeHandle, out string sql)) { var key = GetSingleKey(nameof(Get)); + var columnAttribute = key.GetCustomAttribute(); var name = GetTableName(type); - sql = $"select * from {name} where {key.Name} = @id"; + sql = $"select * from {name} where {(columnAttribute == null ? key.Name : columnAttribute.Name)} = @id"; GetQueries[type.TypeHandle] = sql; } From a9522d68a6a24366f35fa042b13c55f09194f74c Mon Sep 17 00:00:00 2001 From: "lena.tauchner" Date: Thu, 3 Feb 2022 00:11:05 +0100 Subject: [PATCH 6/8] Refactored ColumnName to be gotten from method and removed it at some points (testing) --- src/Dapper.Contrib/Dapper.Contrib.csproj | 7 +++- .../SqlMapperExtensions.Async.cs | 21 ++++------ src/Dapper.Contrib/SqlMapperExtensions.cs | 39 +++++++------------ 3 files changed, 29 insertions(+), 38 deletions(-) diff --git a/src/Dapper.Contrib/Dapper.Contrib.csproj b/src/Dapper.Contrib/Dapper.Contrib.csproj index 86a0cbb2..5d828d9d 100644 --- a/src/Dapper.Contrib/Dapper.Contrib.csproj +++ b/src/Dapper.Contrib/Dapper.Contrib.csproj @@ -4,10 +4,15 @@ Dapper.Contrib orm;sql;micro-orm;dapper The official collection of get, insert, update and delete helpers for Dapper.net. Also handles lists of entities and optional "dirty" tracking of interface-based entities. - Sam Saffron;Johan Danforth + Sam Saffron;Johan Danforth;Tiefseetauchner 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 diff --git a/src/Dapper.Contrib/SqlMapperExtensions.Async.cs b/src/Dapper.Contrib/SqlMapperExtensions.Async.cs index a60e4cb1..7ad24fe6 100644 --- a/src/Dapper.Contrib/SqlMapperExtensions.Async.cs +++ b/src/Dapper.Contrib/SqlMapperExtensions.Async.cs @@ -51,9 +51,7 @@ public static async Task GetAsync(this IDbConnection connection, dynamic i foreach (var property in TypePropertiesCache(type)) { - var columnAttribute = property.GetCustomAttribute(); - - var val = res[columnAttribute == null ? property.Name : columnAttribute.Name]; + var val = res[property.Name]; if (val == null) continue; if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) { @@ -112,9 +110,7 @@ private static async Task> GetAllAsyncImpl(IDbConnection conne var obj = ProxyGenerator.GetInterfaceProxy(); foreach (var property in TypePropertiesCache(type)) { - var columnAttribute = property.GetCustomAttribute(); - - var val = res[columnAttribute == null ? property.Name : columnAttribute.Name]; + var val = res[property.Name]; if (val == null) continue; if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) { @@ -181,7 +177,7 @@ public static Task InsertAsync(this IDbConnection connection, T entityTo var columnAttribute = property.GetCustomAttribute(); - sqlAdapter.AppendColumnName(sbColumnList, columnAttribute == null ? property.Name : columnAttribute.Name); + sqlAdapter.AppendColumnName(sbColumnList, GetColumnName(property)); if (i < allPropertiesExceptKeyAndComputed.Count - 1) sbColumnList.Append(", "); } @@ -265,7 +261,7 @@ public static async Task UpdateAsync(this IDbConnection connection, T e var columnAttribute = property.GetCustomAttribute(); - adapter.AppendColumnNameEqualsValue(sb, columnAttribute == null ? property.Name : columnAttribute.Name, property.Name); + adapter.AppendColumnNameEqualsValue(sb, GetColumnName(property), property.Name); if (i < nonIdProps.Count - 1) sb.Append(", "); } @@ -276,7 +272,7 @@ public static async Task UpdateAsync(this IDbConnection connection, T e var columnAttribute = property.GetCustomAttribute(); - adapter.AppendColumnNameEqualsValue(sb, columnAttribute == null ? property.Name : columnAttribute.Name, property.Name); + adapter.AppendColumnNameEqualsValue(sb, GetColumnName(property), property.Name); if (i < keyProperties.Count - 1) sb.Append(" and "); } @@ -336,7 +332,7 @@ public static async Task DeleteAsync(this IDbConnection connection, T e var columnAttribute = property.GetCustomAttribute(); - adapter.AppendColumnNameEqualsValue(sb, columnAttribute == null ? property.Name : columnAttribute.Name, property.Name); + adapter.AppendColumnNameEqualsValue(sb, GetColumnName(property), property.Name); if (i < allKeyProperties.Count - 1) sb.Append(" AND "); } @@ -513,9 +509,7 @@ public async Task InsertAsync(IDbConnection connection, IDbTransaction tran sb.Append(", "); first = false; - var columnAttribute = property.GetCustomAttribute(); - - sb.Append(columnAttribute == null ? property.Name : columnAttribute.Name); + sb.Append(GetColumnName(property)); } } @@ -532,6 +526,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 fb6b7887..a01bc3e6 100644 --- a/src/Dapper.Contrib/SqlMapperExtensions.cs +++ b/src/Dapper.Contrib/SqlMapperExtensions.cs @@ -175,10 +175,9 @@ public static T Get(this IDbConnection connection, dynamic id, IDbTransaction if (!GetQueries.TryGetValue(type.TypeHandle, out string sql)) { var key = GetSingleKey(nameof(Get)); - var columnAttribute = key.GetCustomAttribute(); var name = GetTableName(type); - sql = $"select * from {name} where {(columnAttribute == null ? key.Name : columnAttribute.Name)} = @id"; + sql = $"select * from {name} where {GetColumnName(key)} = @id"; GetQueries[type.TypeHandle] = sql; } @@ -199,9 +198,8 @@ public static T Get(this IDbConnection connection, dynamic id, IDbTransaction foreach (var property in TypePropertiesCache(type)) { - var columnAttribute = property.GetCustomAttribute(); - var val = res[columnAttribute == null ? property.Name : columnAttribute.Name]; + var val = res[property.Name]; if (val == null) continue; if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) { @@ -257,9 +255,7 @@ public static IEnumerable GetAll(this IDbConnection connection, IDbTransac var obj = ProxyGenerator.GetInterfaceProxy(); foreach (var property in TypePropertiesCache(type)) { - var columnAttribute = property.GetCustomAttribute(); - - var val = res[columnAttribute == null ? property.Name : columnAttribute.Name]; + var val = res[property.Name]; if (val == null) continue; if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) { @@ -362,9 +358,7 @@ public static long Insert(this IDbConnection connection, T entityToInsert, ID { var property = allPropertiesExceptKeyAndComputed[i]; - var columnAttribute = property.GetCustomAttribute(); - - adapter.AppendColumnName(sbColumnList, columnAttribute == null ? property.Name : columnAttribute.Name); + adapter.AppendColumnName(sbColumnList, GetColumnName(property)); if (i < allPropertiesExceptKeyAndComputed.Count - 1) sbColumnList.Append(", "); @@ -398,7 +392,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. /// @@ -454,9 +448,8 @@ public static bool Update(this IDbConnection connection, T entityToUpdate, ID for (var i = 0; i < nonIdProps.Count; i++) { var property = nonIdProps[i]; - var columnAttribute = property.GetCustomAttribute(); - adapter.AppendColumnNameEqualsValue(sb, columnAttribute == null ? property.Name : columnAttribute.Name, property.Name); + adapter.AppendColumnNameEqualsValue(sb, GetColumnName(property), property.Name); if (i < nonIdProps.Count - 1) sb.Append(", "); } @@ -465,9 +458,7 @@ public static bool Update(this IDbConnection connection, T entityToUpdate, ID { var property = keyProperties[i]; - var columnAttribute = property.GetCustomAttribute(); - - adapter.AppendColumnNameEqualsValue(sb, columnAttribute == null ? property.Name : columnAttribute.Name, 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 "); } @@ -525,9 +516,8 @@ public static bool Delete(this IDbConnection connection, T entityToDelete, ID { var property = keyProperties[i]; - var columnAttribute = property.GetCustomAttribute(); - adapter.AppendColumnNameEqualsValue(sb, columnAttribute == null ? property.Name : columnAttribute.Name, 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 "); } @@ -609,9 +599,7 @@ public static T GetInterfaceProxy() { var isId = property.GetCustomAttributes(true).Any(a => a is KeyAttribute); - var columnAttribute = property.GetCustomAttribute(); - - CreateProperty(typeBuilder, columnAttribute == null ? property.Name : columnAttribute.Name, property.PropertyType, setIsDirtyMethod, isId); + CreateProperty(typeBuilder, GetColumnName(property), property.PropertyType, setIsDirtyMethod, isId); } #if NETSTANDARD2_0 @@ -721,6 +709,11 @@ 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; } /// @@ -1054,9 +1047,7 @@ public int Insert(IDbConnection connection, IDbTransaction transaction, int? com sb.Append(", "); first = false; - var columnAttribute = property.GetCustomAttribute(); - - sb.Append(columnAttribute == null ? property.Name : columnAttribute.Name); + sb.Append(GetColumnName(property)); } } From 8cdd4425064c8abaeea0f678703ae5e75f5a26f0 Mon Sep 17 00:00:00 2001 From: "lena.tauchner" Date: Thu, 3 Feb 2022 01:31:10 +0100 Subject: [PATCH 7/8] Added alias to select in get methods to allow for mapping to properties --- .../SqlMapperExtensions.Async.cs | 55 +++++++- src/Dapper.Contrib/SqlMapperExtensions.cs | 124 +++++++++++++++++- 2 files changed, 170 insertions(+), 9 deletions(-) diff --git a/src/Dapper.Contrib/SqlMapperExtensions.Async.cs b/src/Dapper.Contrib/SqlMapperExtensions.Async.cs index 7ad24fe6..6f19afa8 100644 --- a/src/Dapper.Contrib/SqlMapperExtensions.Async.cs +++ b/src/Dapper.Contrib/SqlMapperExtensions.Async.cs @@ -29,10 +29,32 @@ public static async Task GetAsync(this IDbConnection connection, dynamic i if (!GetQueries.TryGetValue(type.TypeHandle, out string sql)) { var key = GetSingleKey(nameof(GetAsync)); - var columnAttribute = key.GetCustomAttribute(); var name = GetTableName(type); + + var sb = new StringBuilder(); + + var allProperties = TypePropertiesCache(type); - sql = $"SELECT * FROM {name} WHERE {(columnAttribute == null ? key.Name : columnAttribute.Name)} = @id"; + 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; } @@ -90,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; } @@ -175,8 +220,6 @@ public static Task InsertAsync(this IDbConnection connection, T entityTo { var property = allPropertiesExceptKeyAndComputed[i]; - var columnAttribute = property.GetCustomAttribute(); - sqlAdapter.AppendColumnName(sbColumnList, GetColumnName(property)); if (i < allPropertiesExceptKeyAndComputed.Count - 1) sbColumnList.Append(", "); @@ -259,8 +302,6 @@ public static async Task UpdateAsync(this IDbConnection connection, T e { var property = nonIdProps[i]; - var columnAttribute = property.GetCustomAttribute(); - adapter.AppendColumnNameEqualsValue(sb, GetColumnName(property), property.Name); if (i < nonIdProps.Count - 1) sb.Append(", "); diff --git a/src/Dapper.Contrib/SqlMapperExtensions.cs b/src/Dapper.Contrib/SqlMapperExtensions.cs index a01bc3e6..2efef3b2 100644 --- a/src/Dapper.Contrib/SqlMapperExtensions.cs +++ b/src/Dapper.Contrib/SqlMapperExtensions.cs @@ -177,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 {GetColumnName(key)} = @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; } @@ -241,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); - sql = "select * from " + name; + 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; } @@ -714,6 +760,7 @@ private static void CreateProperty(TypeBuilder typeBuilder, string propertyNa /// 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; } /// @@ -837,6 +884,13 @@ public partial interface ISqlAdapter /// The column name. /// 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); } /// @@ -894,6 +948,17 @@ public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName, str { 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); + } } /// @@ -951,6 +1016,17 @@ public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName, str { 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); + } } /// @@ -1007,6 +1083,17 @@ public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName, str { 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); + } } /// @@ -1085,6 +1172,17 @@ public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName, str { 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); + } } /// @@ -1139,6 +1237,17 @@ public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName, str { 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); + } } /// @@ -1197,4 +1306,15 @@ public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName, str { 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); + } } From fda803c5b6b1bbb563a01ed4aedfd9fcee80b6e9 Mon Sep 17 00:00:00 2001 From: Lena <48085877+Tiefseetauchner@users.noreply.github.com> Date: Sat, 28 Oct 2023 13:16:04 +0200 Subject: [PATCH 8/8] Update Dapper.Contrib.csproj --- src/Dapper.Contrib/Dapper.Contrib.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Dapper.Contrib/Dapper.Contrib.csproj b/src/Dapper.Contrib/Dapper.Contrib.csproj index 5d828d9d..76c10ffa 100644 --- a/src/Dapper.Contrib/Dapper.Contrib.csproj +++ b/src/Dapper.Contrib/Dapper.Contrib.csproj @@ -4,7 +4,7 @@ Dapper.Contrib orm;sql;micro-orm;dapper The official collection of get, insert, update and delete helpers for Dapper.net. Also handles lists of entities and optional "dirty" tracking of interface-based entities. - Sam Saffron;Johan Danforth;Tiefseetauchner + Sam Saffron;Johan Danforth net461;netstandard2.0;net5.0 false $(NoWarn);CA1050 @@ -24,4 +24,4 @@ - \ No newline at end of file +