diff --git a/.gitignore b/.gitignore
index 8d001e7fe..238ed4abd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,4 +15,6 @@ NuGet.exe
Test.DB.*
TestResults/
Dapper.Tests/*.sdf
-.dotnet/*
\ No newline at end of file
+.dotnet/*
+.idea.*/
+Dapper.userprefs
\ No newline at end of file
diff --git a/Dapper.Contrib/SqlMapperExtensions.Async.cs b/Dapper.Contrib/SqlMapperExtensions.Async.cs
index f4c320680..5b3f59851 100644
--- a/Dapper.Contrib/SqlMapperExtensions.Async.cs
+++ b/Dapper.Contrib/SqlMapperExtensions.Async.cs
@@ -14,9 +14,9 @@ namespace Dapper.Contrib.Extensions
public static partial class SqlMapperExtensions
{
///
- /// Returns a single entity by a single id from table "Ts" asynchronously using .NET 4.5 Task. T must be of interface type.
+ /// Returns a single entity by a single id from table "Ts" asynchronously using .NET 4.5 Task. T must be of interface type.
/// Id must be marked with [Key] attribute.
- /// Created entity is tracked/intercepted for changes and used by the Update() extension.
+ /// Created entity is tracked/intercepted for changes and used by the Update() extension.
///
/// Interface type to create and populate
/// Open SqlConnection
@@ -33,7 +33,26 @@ public static async Task GetAsync(this IDbConnection connection, dynamic i
var key = GetSingleKey(nameof(GetAsync));
var name = GetTableName(type);
- sql = $"SELECT * FROM {name} WHERE {key.Name} = @id";
+ var aliasedColumns = new StringBuilder();
+
+ if(GetPersistentColumns == DefaultGetPersistentColumns)
+ {
+ aliasedColumns.Append("*");
+ }
+ else
+ {
+ var adapter = GetFormatter(connection);
+ var allCols = GetAllColumns(type);
+ for (var i=0; i GetAsync(this IDbConnection connection, dynamic i
foreach (var property in TypePropertiesCache(type))
{
- var val = res[property.Name];
- property.SetValue(obj, Convert.ChangeType(val, property.PropertyType), null);
+ var val = res[property.ColumnName];
+ property.PropertyInfo.SetValue(obj, Convert.ChangeType(val, property.PropertyInfo.PropertyType), null);
}
((IProxy)obj).IsDirty = false; //reset change tracking and return
@@ -62,10 +81,10 @@ public static async Task GetAsync(this IDbConnection connection, dynamic i
}
///
- /// Returns a list of entites from table "Ts".
+ /// Returns a list of entites from table "Ts".
/// Id of T must be marked with [Key] attribute.
/// Entities created from interfaces are tracked/intercepted for changes and used by the Update() extension
- /// for optimal performance.
+ /// for optimal performance.
///
/// Interface or type to create and populate
/// Open SqlConnection
@@ -83,7 +102,18 @@ public static Task> GetAllAsync(this IDbConnection connection,
GetSingleKey(nameof(GetAll));
var name = GetTableName(type);
- sql = "SELECT * FROM " + name;
+ var adapter = GetFormatter(connection);
+ var aliasedColumns = new StringBuilder();
+ var allCols = GetAllColumns(type);
+ for (var i=0; i> GetAllAsyncImpl(IDbConnection conne
var obj = ProxyGenerator.GetInterfaceProxy();
foreach (var property in TypePropertiesCache(type))
{
- var val = res[property.Name];
- property.SetValue(obj, Convert.ChangeType(val, property.PropertyType), null);
+ var val = res[property.ColumnName];
+ property.PropertyInfo.SetValue(obj, Convert.ChangeType(val, property.PropertyInfo.PropertyType), null);
}
((IProxy)obj).IsDirty = false; //reset change tracking and return
list.Add(obj);
@@ -142,25 +172,23 @@ public static Task InsertAsync(this IDbConnection connection, T entityTo
var name = GetTableName(type);
var sbColumnList = new StringBuilder(null);
- var allProperties = TypePropertiesCache(type);
+ var persistentProperties = PersistentPropertiesCache(type);
var keyProperties = KeyPropertiesCache(type);
- var computedProperties = ComputedPropertiesCache(type);
- var allPropertiesExceptKeyAndComputed = allProperties.Except(keyProperties.Union(computedProperties)).ToList();
- for (var i = 0; i < allPropertiesExceptKeyAndComputed.Count; i++)
+ for (var i = 0; i < persistentProperties.Count; i++)
{
- var property = allPropertiesExceptKeyAndComputed.ElementAt(i);
- sqlAdapter.AppendColumnName(sbColumnList, property.Name);
- if (i < allPropertiesExceptKeyAndComputed.Count - 1)
+ var property = persistentProperties.ElementAt(i);
+ sqlAdapter.AppendColumnName(sbColumnList, property.ColumnName);
+ if (i < persistentProperties.Count - 1)
sbColumnList.Append(", ");
}
var sbParameterList = new StringBuilder(null);
- for (var i = 0; i < allPropertiesExceptKeyAndComputed.Count; i++)
+ for (var i = 0; i < persistentProperties.Count; i++)
{
- var property = allPropertiesExceptKeyAndComputed.ElementAt(i);
- sbParameterList.AppendFormat("@{0}", property.Name);
- if (i < allPropertiesExceptKeyAndComputed.Count - 1)
+ var property = persistentProperties.ElementAt(i);
+ sbParameterList.AppendFormat("@{0}", property.PropertyInfo.Name);
+ if (i < persistentProperties.Count - 1)
sbParameterList.Append(", ");
}
@@ -204,34 +232,30 @@ public static async Task UpdateAsync(this IDbConnection connection, T e
}
var keyProperties = KeyPropertiesCache(type);
- var explicitKeyProperties = ExplicitKeyPropertiesCache(type);
- if (!keyProperties.Any() && !explicitKeyProperties.Any())
- throw new ArgumentException("Entity must have at least one [Key] or [ExplicitKey] property");
+ if (!keyProperties.Any())
+ throw new ArgumentException("Entity must have at least one key property, defined by GetKeyProperties. By default, use [Key] or [ExplicitKey] property");
var name = GetTableName(type);
var sb = new StringBuilder();
sb.AppendFormat("update {0} set ", name);
- var allProperties = TypePropertiesCache(type);
- keyProperties.AddRange(explicitKeyProperties);
- var computedProperties = ComputedPropertiesCache(type);
- var nonIdProps = allProperties.Except(keyProperties.Union(computedProperties)).ToList();
+ var persistentProperties = PersistentPropertiesCache(type);
var adapter = GetFormatter(connection);
- for (var i = 0; i < nonIdProps.Count; i++)
+ for (var i = 0; i < persistentProperties.Count; i++)
{
- var property = nonIdProps.ElementAt(i);
- adapter.AppendColumnNameEqualsValue(sb, property.Name);
- if (i < nonIdProps.Count - 1)
+ var property = persistentProperties.ElementAt(i);
+ adapter.AppendColumnNameEqualsValue(sb, property.ColumnName, property.PropertyInfo.Name);
+ if (i < persistentProperties.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);
+ adapter.AppendColumnNameEqualsValue(sb, property.ColumnName, property.PropertyInfo.Name);
if (i < keyProperties.Count - 1)
sb.AppendFormat(" and ");
}
@@ -265,12 +289,10 @@ public static async Task DeleteAsync(this IDbConnection connection, T e
}
var keyProperties = KeyPropertiesCache(type);
- var explicitKeyProperties = ExplicitKeyPropertiesCache(type);
- if (!keyProperties.Any() && !explicitKeyProperties.Any())
- throw new ArgumentException("Entity must have at least one [Key] or [ExplicitKey] property");
+ if (!keyProperties.Any())
+ throw new ArgumentException("Entity must have at least one key property, defined by GetKeyProperties. By default, use [Key] or [ExplicitKey] property");
var name = GetTableName(type);
- keyProperties.AddRange(explicitKeyProperties);
var sb = new StringBuilder();
sb.AppendFormat("DELETE FROM {0} WHERE ", name);
@@ -278,7 +300,7 @@ public static async Task DeleteAsync(this IDbConnection connection, T e
for (var i = 0; i < keyProperties.Count; i++)
{
var property = keyProperties.ElementAt(i);
- sb.AppendFormat("{0} = @{1}", property.Name, property.Name);
+ sb.AppendFormat("{0} = @{1}", property.ColumnName, property.ColumnName);
if (i < keyProperties.Count - 1)
sb.AppendFormat(" AND ");
}
@@ -306,12 +328,12 @@ public static async Task DeleteAllAsync(this IDbConnection connection,
public partial interface ISqlAdapter
{
- Task InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, String tableName, string columnList, string parameterList, IEnumerable keyProperties, object entityToInsert);
+ Task InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, String tableName, string columnList, string parameterList, IList keyProperties, object entityToInsert);
}
public partial class SqlServerAdapter
{
- public async Task InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, String tableName, string columnList, string parameterList, IEnumerable keyProperties, object entityToInsert)
+ public async Task InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, String tableName, string columnList, string parameterList, IList keyProperties, object entityToInsert)
{
var cmd = $"INSERT INTO {tableName} ({columnList}) values ({parameterList}); SELECT SCOPE_IDENTITY() id";
var multi = await connection.QueryMultipleAsync(cmd, entityToInsert, transaction, commandTimeout);
@@ -320,10 +342,10 @@ public async Task InsertAsync(IDbConnection connection, IDbTransaction tran
if (first == null || first.id == null) return 0;
var id = (int)first.id;
- var pi = keyProperties as PropertyInfo[] ?? keyProperties.ToArray();
- if (!pi.Any()) return id;
- var idp = pi.First();
+ if (!keyProperties.Any()) return id;
+
+ var idp = keyProperties.First().PropertyInfo;
idp.SetValue(entityToInsert, Convert.ChangeType(id, idp.PropertyType), null);
return id;
@@ -332,7 +354,7 @@ public async Task InsertAsync(IDbConnection connection, IDbTransaction tran
public partial class SqlCeServerAdapter
{
- public async Task InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable keyProperties, object entityToInsert)
+ public async Task InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IList keyProperties, object entityToInsert)
{
var cmd = $"INSERT INTO {tableName} ({columnList}) VALUES ({parameterList})";
await connection.ExecuteAsync(cmd, entityToInsert, transaction, commandTimeout).ConfigureAwait(false);
@@ -341,10 +363,9 @@ public async Task InsertAsync(IDbConnection connection, IDbTransaction tran
if (r.First() == null || r.First().id == null) return 0;
var id = (int)r.First().id;
- var pi = keyProperties as PropertyInfo[] ?? keyProperties.ToArray();
- if (!pi.Any()) return id;
+ if (!keyProperties.Any()) return id;
- var idp = pi.First();
+ var idp = keyProperties.First().PropertyInfo;
idp.SetValue(entityToInsert, Convert.ChangeType(id, idp.PropertyType), null);
return id;
@@ -354,7 +375,7 @@ public async Task InsertAsync(IDbConnection connection, IDbTransaction tran
public partial class MySqlAdapter
{
public async Task InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName,
- string columnList, string parameterList, IEnumerable keyProperties, object entityToInsert)
+ string columnList, string parameterList, IList keyProperties, object entityToInsert)
{
var cmd = $"INSERT INTO {tableName} ({columnList}) VALUES ({parameterList})";
await connection.ExecuteAsync(cmd, entityToInsert, transaction, commandTimeout).ConfigureAwait(false);
@@ -362,10 +383,9 @@ public async Task InsertAsync(IDbConnection connection, IDbTransaction tran
var id = r.First().id;
if (id == null) return 0;
- var pi = keyProperties as PropertyInfo[] ?? keyProperties.ToArray();
- if (!pi.Any()) return Convert.ToInt32(id);
+ if (!keyProperties.Any()) return Convert.ToInt32(id);
- var idp = pi.First();
+ var idp = keyProperties.First().PropertyInfo;
idp.SetValue(entityToInsert, Convert.ChangeType(id, idp.PropertyType), null);
return Convert.ToInt32(id);
@@ -373,26 +393,25 @@ public async Task InsertAsync(IDbConnection connection, IDbTransaction tran
}
public partial class PostgresAdapter
-{
- public async Task InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable keyProperties, object entityToInsert)
+{
+ public async Task InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IList keyProperties, object entityToInsert)
{
var sb = new StringBuilder();
sb.AppendFormat("INSERT INTO {0} ({1}) VALUES ({2})", tableName, columnList, parameterList);
// If no primary key then safe to assume a join table with not too much data to return
- var propertyInfos = keyProperties as PropertyInfo[] ?? keyProperties.ToArray();
- if (!propertyInfos.Any())
+ if (!keyProperties.Any())
sb.Append(" RETURNING *");
else
{
sb.Append(" RETURNING ");
bool first = true;
- foreach (var property in propertyInfos)
+ foreach (var property in keyProperties)
{
if (!first)
sb.Append(", ");
first = false;
- sb.Append(property.Name);
+ sb.Append(property.ColumnName);
}
}
@@ -401,10 +420,10 @@ public async Task InsertAsync(IDbConnection connection, IDbTransaction tran
// Return the key by assinging the corresponding property in the object - by product is that it supports compound primary keys
var id = 0;
var values = results.First();
- foreach (var p in propertyInfos)
+ foreach (var p in keyProperties)
{
- var value = values[p.Name.ToLower()];
- p.SetValue(entityToInsert, value, null);
+ var value = values[p.ColumnName.ToLower()];
+ p.PropertyInfo.SetValue(entityToInsert, value, null);
if (id == 0)
id = Convert.ToInt32(value);
}
@@ -414,19 +433,18 @@ public async Task InsertAsync(IDbConnection connection, IDbTransaction tran
public partial class SQLiteAdapter
{
- public async Task InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable keyProperties, object entityToInsert)
+ public async Task InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IList keyProperties, object entityToInsert)
{
var cmd = $"INSERT INTO {tableName} ({columnList}) VALUES ({parameterList}); SELECT last_insert_rowid() id";
var multi = await connection.QueryMultipleAsync(cmd, entityToInsert, transaction, commandTimeout);
var id = (int)multi.Read().First().id;
- var pi = keyProperties as PropertyInfo[] ?? keyProperties.ToArray();
- if (!pi.Any()) return id;
+ if (!keyProperties.Any()) return id;
- var idp = pi.First();
+ var idp = keyProperties.First().PropertyInfo;
idp.SetValue(entityToInsert, Convert.ChangeType(id, idp.PropertyType), null);
return id;
}
}
-#endif
+#endif
diff --git a/Dapper.Contrib/SqlMapperExtensions.cs b/Dapper.Contrib/SqlMapperExtensions.cs
index 11c947b26..6e37f9a6c 100644
--- a/Dapper.Contrib/SqlMapperExtensions.cs
+++ b/Dapper.Contrib/SqlMapperExtensions.cs
@@ -32,11 +32,11 @@ public interface ITableNameMapper
public delegate string GetDatabaseTypeDelegate(IDbConnection connection);
public delegate string TableNameMapperDelegate(Type type);
+ public delegate List ColumnNameMapperDelegate(Type type);
- private static readonly ConcurrentDictionary> KeyProperties = new ConcurrentDictionary>();
- private static readonly ConcurrentDictionary> ExplicitKeyProperties = new ConcurrentDictionary>();
- private static readonly ConcurrentDictionary> TypeProperties = new ConcurrentDictionary>();
- private static readonly ConcurrentDictionary> ComputedProperties = new ConcurrentDictionary>();
+ private static readonly ConcurrentDictionary> KeyProperties = new ConcurrentDictionary>();
+ private static readonly ConcurrentDictionary> TypeProperties = new ConcurrentDictionary>();
+ private static readonly ConcurrentDictionary> PersistentProperties = new ConcurrentDictionary>();
private static readonly ConcurrentDictionary GetQueries = new ConcurrentDictionary();
private static readonly ConcurrentDictionary TypeTableName = new ConcurrentDictionary();
@@ -51,75 +51,100 @@ private static readonly Dictionary AdapterDictionary
{"mysqlconnection", new MySqlAdapter()},
};
- private static List ComputedPropertiesCache(Type type)
+ private static PropertyMap MapProperty(PropertyInfo propInfo)
{
- IEnumerable pi;
- if (ComputedProperties.TryGetValue(type.TypeHandle, out pi))
- {
- return pi.ToList();
- }
-
- var computedProperties = TypePropertiesCache(type).Where(p => p.GetCustomAttributes(true).Any(a => a is ComputedAttribute)).ToList();
-
- ComputedProperties[type.TypeHandle] = computedProperties;
- return computedProperties;
+ return new PropertyMap(propInfo.Name, propInfo);
}
- private static List ExplicitKeyPropertiesCache(Type type)
+ public static ColumnNameMapperDelegate GetKeyColumns = DefaultGetKeyColumns;
+ private static List DefaultGetKeyColumns(Type type)
{
- IEnumerable pi;
- if (ExplicitKeyProperties.TryGetValue(type.TypeHandle, out pi))
+ var allProperties = TypePropertiesCache(type);
+ var keyProperties = allProperties.Where(p => p.PropertyInfo.GetCustomAttributes(true)
+ .Any(a => a is KeyAttribute))
+ .ToList();
+
+ if (keyProperties.Count == 0)
{
- return pi.ToList();
+ var idProp = allProperties.FirstOrDefault(p => p.PropertyInfo.Name.ToLower() == "id");
+ if (idProp != null)
+ {
+ keyProperties.Add(idProp);
+ }
}
- var explicitKeyProperties = TypePropertiesCache(type).Where(p => p.GetCustomAttributes(true).Any(a => a is ExplicitKeyAttribute)).ToList();
+ var explicitKeyProperties = TypePropertiesCache(type)
+ .Where(p => !keyProperties.Contains(p)
+ && p.PropertyInfo.GetCustomAttributes(true).Any(a => a is ExplicitKeyAttribute))
+ .ToList();
+
- ExplicitKeyProperties[type.TypeHandle] = explicitKeyProperties;
- return explicitKeyProperties;
+ keyProperties.AddRange(explicitKeyProperties);
+
+ return keyProperties;
}
- private static List KeyPropertiesCache(Type type)
+ private static List KeyPropertiesCache(Type type)
{
-
- IEnumerable pi;
+ IEnumerable pi;
if (KeyProperties.TryGetValue(type.TypeHandle, out pi))
{
return pi.ToList();
}
- var allProperties = TypePropertiesCache(type);
- var keyProperties = allProperties.Where(p =>
- {
- return p.GetCustomAttributes(true).Any(a => a is KeyAttribute);
- }).ToList();
-
- if (keyProperties.Count == 0)
- {
- var idProp = allProperties.FirstOrDefault(p => p.Name.ToLower() == "id");
- if (idProp != null && !idProp.GetCustomAttributes(true).Any(a => a is ExplicitKeyAttribute))
- {
- keyProperties.Add(idProp);
- }
- }
+ var keyProperties = GetKeyColumns(type);
KeyProperties[type.TypeHandle] = keyProperties;
return keyProperties;
}
- private static List TypePropertiesCache(Type type)
+ public static ColumnNameMapperDelegate GetAllColumns = DefaultGetAllColumns;
+ private static List DefaultGetAllColumns(Type type)
{
- IEnumerable pis;
+ return type.GetProperties()
+ .Where(p => IsWriteable(p) && !IsComputed(p))
+ .Select(MapProperty)
+ .ToList();
+ }
+
+ private static List TypePropertiesCache(Type type)
+ {
+ IEnumerable pis;
if (TypeProperties.TryGetValue(type.TypeHandle, out pis))
{
return pis.ToList();
}
- var properties = type.GetProperties().Where(IsWriteable).ToArray();
+ var properties = GetAllColumns(type);
TypeProperties[type.TypeHandle] = properties;
return properties.ToList();
}
+ private static List PersistentPropertiesCache(Type type)
+ {
+ IEnumerable pis;
+ if (PersistentProperties.TryGetValue(type.TypeHandle, out pis))
+ {
+ return pis.ToList();
+ }
+
+ var properties = GetPersistentColumns(type);
+ PersistentProperties[type.TypeHandle] = properties;
+ return properties.ToList();
+ }
+
+ public static ColumnNameMapperDelegate GetPersistentColumns = DefaultGetPersistentColumns;
+ private static List DefaultGetPersistentColumns(Type type)
+ {
+ var keyProperties = KeyPropertiesCache(type)
+ .Where(k => !k.PropertyInfo.GetCustomAttributes(true).Any(a => a is ExplicitKeyAttribute))
+ .Select(k => k.PropertyInfo);
+
+ return TypePropertiesCache(type)
+ .Where(t => !keyProperties.Contains(t.PropertyInfo))
+ .ToList();
+ }
+
private static bool IsWriteable(PropertyInfo pi)
{
var attributes = pi.GetCustomAttributes(typeof(WriteAttribute), false).AsList();
@@ -129,25 +154,30 @@ private static bool IsWriteable(PropertyInfo pi)
return writeAttribute.Write;
}
- private static PropertyInfo GetSingleKey(string method)
+ private static bool IsComputed(PropertyInfo pi)
+ {
+ var attributes = pi.GetCustomAttributes(typeof(ComputedAttribute), false).AsList();
+ return attributes.Any();
+ }
+
+ private static PropertyMap GetSingleKey(string method)
{
var type = typeof (T);
var keys = KeyPropertiesCache(type);
- var explicitKeys = ExplicitKeyPropertiesCache(type);
- var keyCount = keys.Count + explicitKeys.Count;
+ var keyCount = keys.Count;
if (keyCount > 1)
- throw new DataException($"{method} only supports an entity with a single [Key] or [ExplicitKey] property");
+ throw new DataException($"{method} only supports an entity with a single key property, as defined by GetKeyProperties. By default, this is determined by [Key] or [ExplicitKey] attributes");
if (keyCount == 0)
- throw new DataException($"{method} only supports an entity with a [Key] or an [ExplicitKey] property");
+ throw new DataException($"{method} only supports an entity with a key property, as defined by GetKeyProperties. By defualt, this is determined by [Key] or [ExplicitKey] attributes");
- return keys.Any() ? keys.First() : explicitKeys.First();
+ return keys.First();
}
///
- /// Returns a single entity by a single id from table "Ts".
+ /// Returns a single entity by a single id from table "Ts".
/// Id must be marked with [Key] attribute.
/// Entities created from interfaces are tracked/intercepted for changes and used by the Update() extension
- /// for optimal performance.
+ /// for optimal performance.
///
/// Interface or type to create and populate
/// Open SqlConnection
@@ -165,7 +195,26 @@ 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 aliasedColumns = new StringBuilder();
+
+ if(GetPersistentColumns == DefaultGetPersistentColumns)
+ {
+ aliasedColumns.Append("*");
+ }
+ else
+ {
+ var adapter = GetFormatter(connection);
+ var allCols = GetAllColumns(type);
+ for (var i=0; i(this IDbConnection connection, dynamic id, IDbTransaction
foreach (var property in TypePropertiesCache(type))
{
- var val = res[property.Name];
- property.SetValue(obj, Convert.ChangeType(val, property.PropertyType), null);
+ var val = res[property.ColumnName];
+ property.PropertyInfo.SetValue(obj, Convert.ChangeType(val, property.PropertyInfo.PropertyType), null);
}
((IProxy)obj).IsDirty = false; //reset change tracking and return
@@ -199,10 +248,10 @@ public static T Get(this IDbConnection connection, dynamic id, IDbTransaction
}
///
- /// Returns a list of entites from table "Ts".
+ /// Returns a list of entites from table "Ts".
/// Id of T must be marked with [Key] attribute.
/// Entities created from interfaces are tracked/intercepted for changes and used by the Update() extension
- /// for optimal performance.
+ /// for optimal performance.
///
/// Interface or type to create and populate
/// Open SqlConnection
@@ -220,7 +269,19 @@ public static IEnumerable GetAll(this IDbConnection connection, IDbTransac
GetSingleKey(nameof(GetAll));
var name = GetTableName(type);
- sql = "select * from " + name;
+ var adapter = GetFormatter(connection);
+ var aliasedColumns = new StringBuilder();
+ var allCols = GetAllColumns(type);
+ for (var i=0; i GetAll(this IDbConnection connection, IDbTransac
var obj = ProxyGenerator.GetInterfaceProxy();
foreach (var property in TypePropertiesCache(type))
{
- var val = res[property.Name];
- property.SetValue(obj, Convert.ChangeType(val, property.PropertyType), null);
+ var val = res[property.ColumnName];
+ property.PropertyInfo.SetValue(obj, Convert.ChangeType(val, property.PropertyInfo.PropertyType), null);
}
((IProxy)obj).IsDirty = false; //reset change tracking and return
list.Add(obj);
@@ -258,7 +319,7 @@ private static string GetTableName(Type type)
}
else
{
- //NOTE: This as dynamic trick should be able to handle both our own Table-attribute as well as the one in EntityFramework
+ //NOTE: This as dynamic trick should be able to handle both our own Table-attribute as well as the one in EntityFramework
var tableAttr = type
#if COREFX
.GetTypeInfo()
@@ -306,27 +367,25 @@ public static long Insert(this IDbConnection connection, T entityToInsert, ID
var name = GetTableName(type);
var sbColumnList = new StringBuilder(null);
- var allProperties = TypePropertiesCache(type);
var keyProperties = KeyPropertiesCache(type);
- var computedProperties = ComputedPropertiesCache(type);
- var allPropertiesExceptKeyAndComputed = allProperties.Except(keyProperties.Union(computedProperties)).ToList();
+ var persistentProperties = PersistentPropertiesCache(type);
var adapter = GetFormatter(connection);
- for (var i = 0; i < allPropertiesExceptKeyAndComputed.Count; i++)
+ for (var i = 0; i < persistentProperties.Count; i++)
{
- var property = allPropertiesExceptKeyAndComputed.ElementAt(i);
- adapter.AppendColumnName(sbColumnList, property.Name); //fix for issue #336
- if (i < allPropertiesExceptKeyAndComputed.Count - 1)
+ var property = persistentProperties.ElementAt(i);
+ adapter.AppendColumnName(sbColumnList, property.ColumnName); //fix for issue #336
+ if (i < persistentProperties.Count - 1)
sbColumnList.Append(", ");
}
var sbParameterList = new StringBuilder(null);
- for (var i = 0; i < allPropertiesExceptKeyAndComputed.Count; i++)
+ for (var i = 0; i < persistentProperties.Count; i++)
{
- var property = allPropertiesExceptKeyAndComputed.ElementAt(i);
- sbParameterList.AppendFormat("@{0}", property.Name);
- if (i < allPropertiesExceptKeyAndComputed.Count - 1)
+ var property = persistentProperties.ElementAt(i);
+ sbParameterList.AppendFormat("@{0}", property.PropertyInfo.Name);
+ if (i < persistentProperties.Count - 1)
sbParameterList.Append(", ");
}
@@ -377,35 +436,32 @@ public static bool Update(this IDbConnection connection, T entityToUpdate, ID
type = type.GetGenericArguments()[0];
}
- var keyProperties = KeyPropertiesCache(type).ToList(); //added ToList() due to issue #418, must work on a list copy
- var explicitKeyProperties = ExplicitKeyPropertiesCache(type);
- if (!keyProperties.Any() && !explicitKeyProperties.Any())
- throw new ArgumentException("Entity must have at least one [Key] or [ExplicitKey] property");
+ var keyProperties = KeyPropertiesCache(type); //added ToList() due to issue #418, must work on a list copy
+
+ if (!keyProperties.Any())
+ throw new ArgumentException("Entity must have at least one key property, defined by GetKeyProperties. By default, use [Key] or [ExplicitKey] attributes");
var name = GetTableName(type);
var sb = new StringBuilder();
sb.AppendFormat("update {0} set ", name);
- var allProperties = TypePropertiesCache(type);
- keyProperties.AddRange(explicitKeyProperties);
- var computedProperties = ComputedPropertiesCache(type);
- var nonIdProps = allProperties.Except(keyProperties.Union(computedProperties)).ToList();
+ var persistentProperties = PersistentPropertiesCache(type);
- var adapter = GetFormatter(connection);
+ var adapter = GetFormatter(connection);
- for (var i = 0; i < nonIdProps.Count; i++)
+ for (var i = 0; i < persistentProperties.Count; i++)
{
- var property = nonIdProps.ElementAt(i);
- adapter.AppendColumnNameEqualsValue(sb, property.Name); //fix for issue #336
- if (i < nonIdProps.Count - 1)
+ var property = persistentProperties.ElementAt(i);
+ adapter.AppendColumnNameEqualsValue(sb, property.ColumnName, property.PropertyInfo.Name); //fix for issue #336
+ if (i < persistentProperties.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, property.ColumnName, property.PropertyInfo.Name); //fix for issue #336
if (i < keyProperties.Count - 1)
sb.AppendFormat(" and ");
}
@@ -438,13 +494,11 @@ public static bool Delete(this IDbConnection connection, T entityToDelete, ID
type = type.GetGenericArguments()[0];
}
- var keyProperties = KeyPropertiesCache(type).ToList(); //added ToList() due to issue #418, must work on a list copy
- var explicitKeyProperties = ExplicitKeyPropertiesCache(type);
- if (!keyProperties.Any() && !explicitKeyProperties.Any())
- throw new ArgumentException("Entity must have at least one [Key] or [ExplicitKey] property");
+ var keyProperties = KeyPropertiesCache(type);
+ if (!keyProperties.Any())
+ throw new ArgumentException("Entity must have at least one key property, defined by GetKeyProperties. By default, use [Key] or [ExplicitKey] attributes");
var name = GetTableName(type);
- keyProperties.AddRange(explicitKeyProperties);
var sb = new StringBuilder();
sb.AppendFormat("delete from {0} where ", name);
@@ -454,7 +508,7 @@ public static bool Delete(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, property.ColumnName, property.PropertyInfo.Name); //fix for issue #336
if (i < keyProperties.Count - 1)
sb.AppendFormat(" and ");
}
@@ -484,7 +538,7 @@ public static bool DeleteAll(this IDbConnection connection, IDbTransaction tr
/// Please note that this callback is global and will be used by all the calls that require a database specific adapter.
///
public static GetDatabaseTypeDelegate GetDatabaseType;
-
+
private static ISqlAdapter GetFormatter(IDbConnection connection)
{
var name = GetDatabaseType?.Invoke(connection).ToLower()
@@ -591,7 +645,7 @@ private static MethodInfo CreateIsDirtyProperty(TypeBuilder typeBuilder)
private static void CreateProperty(TypeBuilder typeBuilder, string propertyName, Type propType, MethodInfo setIsDirtyMethod, bool isIdentity)
{
- //Define the field and the property
+ //Define the field and the property
var field = typeBuilder.DefineField("_" + propertyName, propType, FieldAttributes.Private);
var property = typeBuilder.DefineProperty(propertyName,
System.Reflection.PropertyAttributes.None,
@@ -688,16 +742,17 @@ public class ComputedAttribute : Attribute
public partial interface ISqlAdapter
{
- int Insert(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable keyProperties, object entityToInsert);
-
+ int Insert(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IList keyProperties, object entityToInsert);
+
//new methods for issue #336
void AppendColumnName(StringBuilder sb, string columnName);
- void AppendColumnNameEqualsValue(StringBuilder sb, string columnName);
+ void AppendColumnNameEqualsValue(StringBuilder sb, string columnName, string propertyName);
+ void AppendAliasedColumn(StringBuilder sb, string columnName, string propertyName);
}
public partial class SqlServerAdapter : ISqlAdapter
{
- public int Insert(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable keyProperties, object entityToInsert)
+ public int Insert(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IList keyProperties, object entityToInsert)
{
var cmd = $"insert into {tableName} ({columnList}) values ({parameterList});select SCOPE_IDENTITY() id";
var multi = connection.QueryMultiple(cmd, entityToInsert, transaction, commandTimeout);
@@ -706,10 +761,9 @@ public int Insert(IDbConnection connection, IDbTransaction transaction, int? com
if (first == null || first.id == null) return 0;
var id = (int)first.id;
- var propertyInfos = keyProperties as PropertyInfo[] ?? keyProperties.ToArray();
- if (!propertyInfos.Any()) return id;
+ if (!keyProperties.Any()) return id;
- var idProperty = propertyInfos.First();
+ var idProperty = keyProperties.First().PropertyInfo;
idProperty.SetValue(entityToInsert, Convert.ChangeType(id, idProperty.PropertyType), null);
return id;
@@ -720,15 +774,20 @@ public void AppendColumnName(StringBuilder sb, string columnName)
sb.AppendFormat("[{0}]", columnName);
}
- public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName)
+ public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName, string propertyName)
+ {
+ sb.AppendFormat("[{0}] = @{1}", columnName, propertyName);
+ }
+
+ public void AppendAliasedColumn(StringBuilder sb, string columnName, string propertyName)
{
- sb.AppendFormat("[{0}] = @{1}", columnName, columnName);
+ sb.AppendFormat("[{0}] as [{1}]", columnName, propertyName);
}
}
public partial class SqlCeServerAdapter : ISqlAdapter
{
- public int Insert(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable keyProperties, object entityToInsert)
+ public int Insert(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IList keyProperties, object entityToInsert)
{
var cmd = $"insert into {tableName} ({columnList}) values ({parameterList})";
connection.Execute(cmd, entityToInsert, transaction, commandTimeout);
@@ -737,10 +796,9 @@ public int Insert(IDbConnection connection, IDbTransaction transaction, int? com
if (r.First().id == null) return 0;
var id = (int) r.First().id;
- var propertyInfos = keyProperties as PropertyInfo[] ?? keyProperties.ToArray();
- if (!propertyInfos.Any()) return id;
+ if (!keyProperties.Any()) return id;
- var idProperty = propertyInfos.First();
+ var idProperty = keyProperties.First().PropertyInfo;
idProperty.SetValue(entityToInsert, Convert.ChangeType(id, idProperty.PropertyType), null);
return id;
@@ -751,15 +809,20 @@ public void AppendColumnName(StringBuilder sb, string columnName)
sb.AppendFormat("[{0}]", columnName);
}
- public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName)
+ public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName, string propertyName)
{
- sb.AppendFormat("[{0}] = @{1}", columnName, columnName);
+ sb.AppendFormat("[{0}] = @{1}", columnName, propertyName);
+ }
+
+ public void AppendAliasedColumn(StringBuilder sb, string columnName, string propertyName)
+ {
+ sb.AppendFormat("[{0}] as [{1}]", columnName, propertyName);
}
}
public partial class MySqlAdapter : ISqlAdapter
{
- public int Insert(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable keyProperties, object entityToInsert)
+ public int Insert(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IList keyProperties, object entityToInsert)
{
var cmd = $"insert into {tableName} ({columnList}) values ({parameterList})";
connection.Execute(cmd, entityToInsert, transaction, commandTimeout);
@@ -767,10 +830,9 @@ public int Insert(IDbConnection connection, IDbTransaction transaction, int? com
var id = r.First().id;
if (id == null) return 0;
- var propertyInfos = keyProperties as PropertyInfo[] ?? keyProperties.ToArray();
- if (!propertyInfos.Any()) return Convert.ToInt32(id);
+ if (!keyProperties.Any()) return Convert.ToInt32(id);
- var idp = propertyInfos.First();
+ var idp = keyProperties.First().PropertyInfo;
idp.SetValue(entityToInsert, Convert.ChangeType(id, idp.PropertyType), null);
return Convert.ToInt32(id);
@@ -781,34 +843,38 @@ public void AppendColumnName(StringBuilder sb, string columnName)
sb.AppendFormat("`{0}`", columnName);
}
- public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName)
+ public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName, string propertyName)
{
- sb.AppendFormat("`{0}` = @{1}", columnName, columnName);
+ sb.AppendFormat("`{0}` = @{1}", columnName, propertyName);
+ }
+
+ public void AppendAliasedColumn(StringBuilder sb, string columnName, string propertyName)
+ {
+ sb.AppendFormat("`{0}` as `{1}`", columnName, propertyName);
}
}
public partial class PostgresAdapter : ISqlAdapter
{
- public int Insert(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable keyProperties, object entityToInsert)
+ public int Insert(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IList keyProperties, object entityToInsert)
{
var sb = new StringBuilder();
sb.AppendFormat("insert into {0} ({1}) values ({2})", tableName, columnList, parameterList);
// If no primary key then safe to assume a join table with not too much data to return
- var propertyInfos = keyProperties as PropertyInfo[] ?? keyProperties.ToArray();
- if (!propertyInfos.Any())
+ if (!keyProperties.Any())
sb.Append(" RETURNING *");
else
{
sb.Append(" RETURNING ");
var first = true;
- foreach (var property in propertyInfos)
+ foreach (var property in keyProperties)
{
if (!first)
sb.Append(", ");
first = false;
- sb.Append(property.Name);
+ sb.Append(property.ColumnName);
}
}
@@ -816,10 +882,10 @@ public int Insert(IDbConnection connection, IDbTransaction transaction, int? com
// Return the key by assinging the corresponding property in the object - by product is that it supports compound primary keys
var id = 0;
- foreach (var p in propertyInfos)
+ foreach (var p in keyProperties)
{
- var value = ((IDictionary)results.First())[p.Name.ToLower()];
- p.SetValue(entityToInsert, value, null);
+ var value = ((IDictionary)results.First())[p.ColumnName.ToLower()];
+ p.PropertyInfo.SetValue(entityToInsert, value, null);
if (id == 0)
id = Convert.ToInt32(value);
}
@@ -831,24 +897,28 @@ public void AppendColumnName(StringBuilder sb, string columnName)
sb.AppendFormat("\"{0}\"", columnName);
}
- public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName)
+ public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName, string propertyName)
{
- sb.AppendFormat("\"{0}\" = @{1}", columnName, columnName);
+ sb.AppendFormat("\"{0}\" = @{1}", columnName, propertyName);
+ }
+
+ public void AppendAliasedColumn(StringBuilder sb, string columnName, string propertyName)
+ {
+ sb.AppendFormat("\"{0}\" as \"{1}\"", columnName, propertyName);
}
}
public partial class SQLiteAdapter : ISqlAdapter
{
- public int Insert(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable keyProperties, object entityToInsert)
+ public int Insert(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IList keyProperties, object entityToInsert)
{
var cmd = $"INSERT INTO {tableName} ({columnList}) VALUES ({parameterList}); SELECT last_insert_rowid() id";
var multi = connection.QueryMultiple(cmd, entityToInsert, transaction, commandTimeout);
var id = (int)multi.Read().First().id;
- var propertyInfos = keyProperties as PropertyInfo[] ?? keyProperties.ToArray();
- if (!propertyInfos.Any()) return id;
+ if (!keyProperties.Any()) return id;
- var idProperty = propertyInfos.First();
+ var idProperty = keyProperties.First().PropertyInfo;
idProperty.SetValue(entityToInsert, Convert.ChangeType(id, idProperty.PropertyType), null);
return id;
@@ -859,8 +929,24 @@ public void AppendColumnName(StringBuilder sb, string columnName)
sb.AppendFormat("\"{0}\"", columnName);
}
- public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName)
+ public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName, string propertyName)
+ {
+ sb.AppendFormat("\"{0}\" = @{1}", columnName, propertyName);
+ }
+
+ public void AppendAliasedColumn(StringBuilder sb, string columnName, string propertyName)
+ {
+ sb.AppendFormat("\"{0}\" as \"{1}\"", columnName, propertyName);
+ }
+}
+
+public class PropertyMap
+{
+ public PropertyMap(string columnName, PropertyInfo propInfo)
{
- sb.AppendFormat("\"{0}\" = @{1}", columnName, columnName);
+ ColumnName = columnName;
+ PropertyInfo = propInfo;
}
+ public string ColumnName { get; private set; }
+ public PropertyInfo PropertyInfo { get; private set; }
}
diff --git a/Dapper.Tests.Contrib/TestSuite.cs b/Dapper.Tests.Contrib/TestSuite.cs
index 02e179182..919d80c3a 100644
--- a/Dapper.Tests.Contrib/TestSuite.cs
+++ b/Dapper.Tests.Contrib/TestSuite.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Data;
using System.Linq;
-
+using System.Reflection;
using Dapper.Contrib.Extensions;
#if !COREFX
@@ -88,6 +88,13 @@ public class Result
public int Order { get; set; }
}
+ [Table("StrangelyMappedThing")]
+ public class StrangelyMappedThing
+ {
+ public int WeirdId { get; set; }
+ public string WonderfullName { get; set; }
+ }
+
public abstract partial class TestSuite
{
protected static readonly bool IsAppVeyor = Environment.GetEnvironmentVariable("Appveyor")?.ToUpperInvariant() == "TRUE";
@@ -171,7 +178,49 @@ public void InsertGetUpdateDeleteWithExplicitKey()
o2.IsNull();
}
}
-
+
+ [Fact]
+ public void InsertGetUpdateDeleteWithOverriddenColumnMaps()
+ {
+ using (var connection = GetOpenConnection())
+ {
+ var idCol = new PropertyMap("strangeId", typeof(StrangelyMappedThing).GetProperty("WeirdId"));
+ var nameCol = new PropertyMap("strangeName", typeof(StrangelyMappedThing).GetProperty("WonderfullName"));
+
+ var origGetAll = SqlMapperExtensions.GetAllColumns;
+ SqlMapperExtensions.GetAllColumns =
+ t => t == typeof(StrangelyMappedThing) ? new List {idCol, nameCol}
+ : origGetAll(t);
+
+ var origGetPersistent = SqlMapperExtensions.GetPersistentColumns;
+ SqlMapperExtensions.GetPersistentColumns =
+ t => t == typeof(StrangelyMappedThing) ? new List {idCol, nameCol}
+ : origGetPersistent(t);
+
+ var origGetKey = SqlMapperExtensions.GetKeyColumns;
+ SqlMapperExtensions.GetKeyColumns =
+ t => t == typeof(StrangelyMappedThing) ? new List {idCol}
+ : origGetKey(t);
+
+ const int id = 1;
+ const string wonderfulName = "foo";
+ var o1 = new StrangelyMappedThing {WeirdId = id, WonderfullName = wonderfulName};
+ var originalxCount = connection.Query("Select Count(*) From StrangelyMappedThing").First();
+ connection.Insert(o1);
+ var list1 = connection.Query("select * from StrangelyMappedThing").ToList();
+ list1.Count.IsEqualTo(originalxCount + 1);
+ o1 = connection.Get(id);
+ o1.WeirdId.IsEqualTo(id);
+ o1.WonderfullName = "bar";
+ connection.Update(o1);
+ o1 = connection.Get(id);
+ o1.WonderfullName.IsEqualTo("bar");
+ connection.Delete(o1);
+ o1 = connection.Get(id);
+ o1.IsNull();
+ }
+ }
+
[Fact]
public void GetAllWithExplicitKey()
{
@@ -187,7 +236,7 @@ public void GetAllWithExplicitKey()
}
}
- [Fact]
+ [Fact]
public void InsertGetUpdateDeleteWithExplicitKeyNamedId()
{
using (var connection = GetOpenConnection())
@@ -208,8 +257,8 @@ public void InsertGetUpdateDeleteWithExplicitKeyNamedId()
//o2.IsNull();
}
}
-
- [Fact]
+
+ [Fact]
public void ShortIdentity()
{
using (var connection = GetOpenConnection())
diff --git a/Dapper.Tests.Contrib/TestSuites.cs b/Dapper.Tests.Contrib/TestSuites.cs
index 320d20eb0..bf549d01f 100644
--- a/Dapper.Tests.Contrib/TestSuites.cs
+++ b/Dapper.Tests.Contrib/TestSuites.cs
@@ -56,6 +56,8 @@ static SqlServerTestSuite()
connection.Execute(@"CREATE TABLE ObjectY (ObjectYId int not null, Name nvarchar(100) not null);");
dropTable("ObjectZ");
connection.Execute(@"CREATE TABLE ObjectZ (Id int not null, Name nvarchar(100) not null);");
+ dropTable("StrangelyMappedThing");
+ connection.Execute(@"CREATE TABLE StrangelyMappedThing (strangeId int not null, strangeName nvarchar(100) not null);");
}
}
}
@@ -104,6 +106,8 @@ static MySqlServerTestSuite()
connection.Execute(@"CREATE TABLE ObjectY (ObjectYId int not null, Name nvarchar(100) not null);");
dropTable("ObjectZ");
connection.Execute(@"CREATE TABLE ObjectZ (Id int not null, Name nvarchar(100) not null);");
+ dropTable("StrangelyMappedThing");
+ connection.Execute(@"CREATE TABLE StrangelyMappedThing (strangeId int not null, strangeName nvarchar(100) not null);");
}
}
catch (MySqlException e)
@@ -145,6 +149,7 @@ static SQLiteTestSuite()
connection.Execute(@"CREATE TABLE ObjectX (ObjectXId nvarchar(100) not null, Name nvarchar(100) not null) ");
connection.Execute(@"CREATE TABLE ObjectY (ObjectYId integer not null, Name nvarchar(100) not null) ");
connection.Execute(@"CREATE TABLE ObjectZ (Id integer not null, Name nvarchar(100) not null) ");
+ connection.Execute(@"CREATE TABLE StrangelyMappedThing (strangeId int not null, strangeName nvarchar(100) not null);");
}
}
}
@@ -156,7 +161,7 @@ public class SqlCETestSuite : TestSuite
const string FileName = "Test.DB.sdf";
public static string ConnectionString => $"Data Source={FileName};";
public override IDbConnection GetConnection() => new SqlCeConnection(ConnectionString);
-
+
static SqlCETestSuite()
{
if (File.Exists(FileName))
@@ -176,6 +181,7 @@ static SqlCETestSuite()
connection.Execute(@"CREATE TABLE ObjectX (ObjectXId nvarchar(100) not null, Name nvarchar(100) not null) ");
connection.Execute(@"CREATE TABLE ObjectY (ObjectYId int not null, Name nvarchar(100) not null) ");
connection.Execute(@"CREATE TABLE ObjectZ (Id int not null, Name nvarchar(100) not null) ");
+ connection.Execute(@"CREATE TABLE StrangelyMappedThing (strangeId int not null, strangeName nvarchar(100) not null);");
}
Console.WriteLine("Created database");
}
diff --git a/Dapper.Tests.Contrib/project.json b/Dapper.Tests.Contrib/project.json
index a4ec28544..1ee2a93e8 100644
--- a/Dapper.Tests.Contrib/project.json
+++ b/Dapper.Tests.Contrib/project.json
@@ -40,7 +40,7 @@
"../Dapper.Tests/XunitSkippable.cs",
"../Dapper/TypeExtensions.cs"
]
- }
+ }
},
"testRunner": "xunit",
"frameworks": {
@@ -112,4 +112,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Dapper.Tests/project.json b/Dapper.Tests/project.json
index 64188982e..3d8b684e0 100644
--- a/Dapper.Tests/project.json
+++ b/Dapper.Tests/project.json
@@ -141,4 +141,4 @@
}
}
}
-}
\ No newline at end of file
+}