Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added: Atrribute Column #681

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Dapper.Contrib/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,16 @@ Dapper.Contrib makes use of some optional attributes:
public string Name { get; set; }
}
```
* `[Column("column_name")]` - use another column name instead of the name of the property

```csharp
public class Employee
{
public int Id { get; set; }
[Column("custom_name")]
public string Name { get; set; }
}
```
* `[Key]` - this property is the identity/key (unless it is named "Id")
* `[Write(true/false)]` - this property is (not) writeable
* `[Computed]` - this property is computed and should not be part of updates
Expand Down
71 changes: 54 additions & 17 deletions Dapper.Contrib/SqlMapperExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,15 @@ public interface ITableNameMapper
public delegate string GetDatabaseTypeDelegate(IDbConnection connection);
public delegate string TableNameMapperDelegate(Type type);

private static readonly ConcurrentDictionary<RuntimeTypeHandle, IEnumerable<PropertyInfo>> KeyProperties = new ConcurrentDictionary<RuntimeTypeHandle, IEnumerable<PropertyInfo>>();
private static readonly ConcurrentDictionary<RuntimeTypeHandle, IEnumerable<PropertyInfo>> KeyProperties = new ConcurrentDictionary<RuntimeTypeHandle, IEnumerable<PropertyInfo>>();
private static readonly ConcurrentDictionary<RuntimeTypeHandle, IEnumerable<PropertyInfo>> ExplicitKeyProperties = new ConcurrentDictionary<RuntimeTypeHandle, IEnumerable<PropertyInfo>>();
private static readonly ConcurrentDictionary<RuntimeTypeHandle, IEnumerable<PropertyInfo>> TypeProperties = new ConcurrentDictionary<RuntimeTypeHandle, IEnumerable<PropertyInfo>>();
private static readonly ConcurrentDictionary<RuntimeTypeHandle, IEnumerable<PropertyInfo>> ComputedProperties = new ConcurrentDictionary<RuntimeTypeHandle, IEnumerable<PropertyInfo>>();
private static readonly ConcurrentDictionary<RuntimeTypeHandle, string> GetQueries = new ConcurrentDictionary<RuntimeTypeHandle, string>();
private static readonly ConcurrentDictionary<RuntimeTypeHandle, string> TypeTableName = new ConcurrentDictionary<RuntimeTypeHandle, string>();
private static readonly ConcurrentDictionary<RuntimeTypeHandle, Dictionary<string, string>> TypePropertyColumnName = new ConcurrentDictionary<RuntimeTypeHandle, Dictionary<string, string>>();

private static readonly ISqlAdapter DefaultAdapter = new SqlServerAdapter();
private static readonly ISqlAdapter DefaultAdapter = new SqlServerAdapter();
private static readonly Dictionary<string, ISqlAdapter> AdapterDictionary
= new Dictionary<string, ISqlAdapter>
{
Expand Down Expand Up @@ -247,7 +248,7 @@ public static IEnumerable<T> GetAll<T>(this IDbConnection connection, IDbTransac
/// </summary>
public static TableNameMapperDelegate TableNameMapper;

private static string GetTableName(Type type)
private static string GetTableName(Type type)
{
string name;
if (TypeTableName.TryGetValue(type.TypeHandle, out name)) return name;
Expand Down Expand Up @@ -276,18 +277,44 @@ private static string GetTableName(Type type)

TypeTableName[type.TypeHandle] = name;
return name;
}
}

private static string GetColumnName(PropertyInfo property)
{
string name;
Type type = property.DeclaringType;
Dictionary<string, string> propertyColumnName = null;

/// <summary>
/// Inserts an entity into table "Ts" and returns identity id or number if inserted rows if inserting a list.
/// </summary>
/// <param name="connection">Open SqlConnection</param>
/// <param name="entityToInsert">Entity to insert, can be list of entities</param>
/// <param name="transaction">The transaction to run under, null (the default) if none</param>
/// <param name="commandTimeout">Number of seconds before command execution timeout</param>
/// <returns>Identity of inserted entity, or number of inserted rows if inserting a list</returns>
public static long Insert<T>(this IDbConnection connection, T entityToInsert, IDbTransaction transaction = null, int? commandTimeout = null) where T : class
if (TypePropertyColumnName.TryGetValue(property.DeclaringType.TypeHandle, out propertyColumnName))
if (propertyColumnName.TryGetValue(property.Name, out name))
return name;

//NOTE: This as dynamic trick should be able to handle both our own Columns-attribute as well as the one in EntityFramework
var columnAttr = property.GetCustomAttributes(false).SingleOrDefault(attr => attr.GetType().Name == "ColumnAttribute") as dynamic;

if (columnAttr != null)
name = columnAttr.Name;
else
name = property.Name;

if (propertyColumnName == null)
TypePropertyColumnName[property.DeclaringType.TypeHandle] = new Dictionary<string, string>();

TypePropertyColumnName[property.DeclaringType.TypeHandle].Add(property.Name, name);

return name;
}


/// <summary>
/// Inserts an entity into table "Ts" and returns identity id or number if inserted rows if inserting a list.
/// </summary>
/// <param name="connection">Open SqlConnection</param>
/// <param name="entityToInsert">Entity to insert, can be list of entities</param>
/// <param name="transaction">The transaction to run under, null (the default) if none</param>
/// <param name="commandTimeout">Number of seconds before command execution timeout</param>
/// <returns>Identity of inserted entity, or number of inserted rows if inserting a list</returns>
public static long Insert<T>(this IDbConnection connection, T entityToInsert, IDbTransaction transaction = null, int? commandTimeout = null) where T : class
{
var isList = false;

Expand Down Expand Up @@ -316,7 +343,7 @@ public static long Insert<T>(this IDbConnection connection, T entityToInsert, ID
for (var i = 0; i < allPropertiesExceptKeyAndComputed.Count; i++)
{
var property = allPropertiesExceptKeyAndComputed.ElementAt(i);
adapter.AppendColumnName(sbColumnList, property.Name); //fix for issue #336
adapter.AppendColumnName(sbColumnList, GetColumnName(property)); //fix for issue #336
if (i < allPropertiesExceptKeyAndComputed.Count - 1)
sbColumnList.Append(", ");
}
Expand Down Expand Up @@ -397,15 +424,15 @@ public static bool Update<T>(this IDbConnection connection, T entityToUpdate, ID
for (var i = 0; i < nonIdProps.Count; i++)
{
var property = nonIdProps.ElementAt(i);
adapter.AppendColumnNameEqualsValue(sb, property.Name); //fix for issue #336
adapter.AppendColumnNameEqualsValue(sb, GetColumnName(property)); //fix for issue #336
if (i < nonIdProps.Count - 1)
sb.AppendFormat(", ");
}
sb.Append(" where ");
for (var i = 0; i < keyProperties.Count; i++)
{
var property = keyProperties.ElementAt(i);
adapter.AppendColumnNameEqualsValue(sb, property.Name); //fix for issue #336
adapter.AppendColumnNameEqualsValue(sb, GetColumnName(property)); //fix for issue #336
if (i < keyProperties.Count - 1)
sb.AppendFormat(" and ");
}
Expand Down Expand Up @@ -454,7 +481,7 @@ public static bool Delete<T>(this IDbConnection connection, T entityToDelete, ID
for (var i = 0; i < keyProperties.Count; i++)
{
var property = keyProperties.ElementAt(i);
adapter.AppendColumnNameEqualsValue(sb, property.Name); //fix for issue #336
adapter.AppendColumnNameEqualsValue(sb, GetColumnName(property)); //fix for issue #336
if (i < keyProperties.Count - 1)
sb.AppendFormat(" and ");
}
Expand Down Expand Up @@ -684,6 +711,16 @@ public WriteAttribute(bool write)
public class ComputedAttribute : Attribute
{
}

[AttributeUsage(AttributeTargets.Property)]
public class ColumnAttribute : Attribute
{
public ColumnAttribute(string columnName)
{
Name = columnName;
}
public string Name { get; set; }
}
}

public partial interface ISqlAdapter
Expand Down