Commit d6e068d3 authored by Johan Danforth's avatar Johan Danforth

Added InsertAsync to Dapper.Contrib and small fix to GetAllAsync

parent f1c1d297
...@@ -15,7 +15,7 @@ namespace Dapper.Contrib.Extensions ...@@ -15,7 +15,7 @@ namespace Dapper.Contrib.Extensions
public static partial class SqlMapperExtensions public static partial class SqlMapperExtensions
{ {
/// <summary> /// <summary>
/// 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. /// Id must be marked with [Key] attribute.
...@@ -41,7 +41,6 @@ public static partial class SqlMapperExtensions ...@@ -41,7 +41,6 @@ public static partial class SqlMapperExtensions
var name = GetTableName(type); var name = GetTableName(type);
// TODO: pluralizer
// TODO: query information schema and only select fields that are both in information schema and underlying class / interface // TODO: query information schema and only select fields that are both in information schema and underlying class / interface
sql = "select * from " + name + " where " + onlyKey.Name + " = @id"; sql = "select * from " + name + " where " + onlyKey.Name + " = @id";
GetQueries[type.TypeHandle] = sql; GetQueries[type.TypeHandle] = sql;
...@@ -50,29 +49,25 @@ public static partial class SqlMapperExtensions ...@@ -50,29 +49,25 @@ public static partial class SqlMapperExtensions
var dynParms = new DynamicParameters(); var dynParms = new DynamicParameters();
dynParms.Add("@id", id); dynParms.Add("@id", id);
T obj;
if (type.IsInterface) if (!type.IsInterface)
{ return (await connection.QueryAsync<T>(sql, dynParms, transaction, commandTimeout).ConfigureAwait(false)).FirstOrDefault();
var res = (await connection.QueryAsync<dynamic>(sql, dynParms).ConfigureAwait(false)).FirstOrDefault() as IDictionary<string, object>;
if (res == null) var res = (await connection.QueryAsync<dynamic>(sql, dynParms).ConfigureAwait(false)).FirstOrDefault() as IDictionary<string, object>;
return null;
obj = ProxyGenerator.GetInterfaceProxy<T>(); if (res == null)
return null;
foreach (var property in TypePropertiesCache(type)) var obj = ProxyGenerator.GetInterfaceProxy<T>();
{
var val = res[property.Name];
property.SetValue(obj, val, null);
}
((IProxy)obj).IsDirty = false; //reset change tracking and return foreach (var property in TypePropertiesCache(type))
}
else
{ {
obj = (await connection.QueryAsync<T>(sql, dynParms, transaction, commandTimeout).ConfigureAwait(false)).FirstOrDefault(); var val = res[property.Name];
property.SetValue(obj, val, null);
} }
((IProxy)obj).IsDirty = false; //reset change tracking and return
return obj; return obj;
} }
...@@ -99,8 +94,6 @@ public static partial class SqlMapperExtensions ...@@ -99,8 +94,6 @@ public static partial class SqlMapperExtensions
if (!keys.Any()) if (!keys.Any())
throw new DataException("Get<T> only supports en entity with a [Key] property"); throw new DataException("Get<T> only supports en entity with a [Key] property");
var onlyKey = keys.First();
var name = GetTableName(type); var name = GetTableName(type);
// TODO: query information schema and only select fields that are both in information schema and underlying class / interface // TODO: query information schema and only select fields that are both in information schema and underlying class / interface
...@@ -115,9 +108,8 @@ public static partial class SqlMapperExtensions ...@@ -115,9 +108,8 @@ public static partial class SqlMapperExtensions
var result = await connection.QueryAsync(sql); var result = await connection.QueryAsync(sql);
var list = new List<T>(); var list = new List<T>();
Parallel.ForEach(result, r => foreach (IDictionary<string, object> res in result)
{ {
var res = r as IDictionary<string, object>;
var obj = ProxyGenerator.GetInterfaceProxy<T>(); var obj = ProxyGenerator.GetInterfaceProxy<T>();
foreach (var property in TypePropertiesCache(type)) foreach (var property in TypePropertiesCache(type))
{ {
...@@ -126,8 +118,7 @@ public static partial class SqlMapperExtensions ...@@ -126,8 +118,7 @@ public static partial class SqlMapperExtensions
} }
((IProxy)obj).IsDirty = false; //reset change tracking and return ((IProxy)obj).IsDirty = false; //reset change tracking and return
list.Add(obj); list.Add(obj);
}
});
return list; return list;
} }
...@@ -138,9 +129,18 @@ public static partial class SqlMapperExtensions ...@@ -138,9 +129,18 @@ public static partial class SqlMapperExtensions
/// <param name="connection">Open SqlConnection</param> /// <param name="connection">Open SqlConnection</param>
/// <param name="entityToInsert">Entity to insert</param> /// <param name="entityToInsert">Entity to insert</param>
/// <returns>Identity of inserted entity</returns> /// <returns>Identity of inserted entity</returns>
public static Task<int> InsertAsync<T>(this IDbConnection connection, T entityToInsert, IDbTransaction transaction = null, int? commandTimeout = null) where T : class public static async Task<int> InsertAsync<T>(this IDbConnection connection, T entityToInsert, IDbTransaction transaction = null, int? commandTimeout = null) where T : class
{ {
var isList = false;
var type = typeof(T); var type = typeof(T);
if (type.IsArray || type.IsGenericType)
{
isList = true;
type = type.GetGenericArguments()[0];
}
var name = GetTableName(type); var name = GetTableName(type);
var sbColumnList = new StringBuilder(null); var sbColumnList = new StringBuilder(null);
var allProperties = TypePropertiesCache(type); var allProperties = TypePropertiesCache(type);
...@@ -164,9 +164,17 @@ public static partial class SqlMapperExtensions ...@@ -164,9 +164,17 @@ public static partial class SqlMapperExtensions
if (i < allPropertiesExceptKeyAndComputed.Count() - 1) if (i < allPropertiesExceptKeyAndComputed.Count() - 1)
sbParameterList.Append(", "); sbParameterList.Append(", ");
} }
var adapter = GetFormatter(connection);
return adapter.InsertAsync(connection, transaction, commandTimeout, name, sbColumnList.ToString(), if (!isList) //single entity
sbParameterList.ToString(), keyProperties, entityToInsert); {
var adapter = GetFormatter(connection);
return await adapter.InsertAsync(connection, transaction, commandTimeout, name, sbColumnList.ToString(),
sbParameterList.ToString(), keyProperties, entityToInsert);
}
//insert list of entities
var cmd = String.Format("insert into {0} ({1}) values ({2})", name, sbColumnList, sbParameterList);
return await connection.ExecuteAsync(cmd, entityToInsert, transaction, commandTimeout);
} }
/// <summary> /// <summary>
......
...@@ -28,6 +28,7 @@ public async Task TableNameAsync() ...@@ -28,6 +28,7 @@ public async Task TableNameAsync()
{ {
using (var connection = GetOpenConnection()) using (var connection = GetOpenConnection())
{ {
connection.DeleteAll<User>();
// tests against "Automobiles" table (Table attribute) // tests against "Automobiles" table (Table attribute)
await connection.InsertAsync(new Car { Name = "Volvo" }); await connection.InsertAsync(new Car { Name = "Volvo" });
(await connection.GetAsync<Car>(1)).Name.IsEqualTo("Volvo"); (await connection.GetAsync<Car>(1)).Name.IsEqualTo("Volvo");
...@@ -42,6 +43,7 @@ public async Task TestSimpleGetAsync() ...@@ -42,6 +43,7 @@ public async Task TestSimpleGetAsync()
{ {
using (var connection = GetOpenConnection()) using (var connection = GetOpenConnection())
{ {
connection.DeleteAll<User>();
var id = await connection.InsertAsync(new User { Name = "Adama", Age = 10 }); var id = await connection.InsertAsync(new User { Name = "Adama", Age = 10 });
var user = await connection.GetAsync<User>(id); var user = await connection.GetAsync<User>(id);
user.Id.IsEqualTo((int)id); user.Id.IsEqualTo((int)id);
...@@ -54,6 +56,7 @@ public async Task InsertGetUpdateAsync() ...@@ -54,6 +56,7 @@ public async Task InsertGetUpdateAsync()
{ {
using (var connection = GetOpenConnection()) using (var connection = GetOpenConnection())
{ {
connection.DeleteAll<User>();
(await connection.GetAsync<User>(3)).IsNull(); (await connection.GetAsync<User>(3)).IsNull();
var id = await connection.InsertAsync(new User { Name = "Adam", Age = 10 }); var id = await connection.InsertAsync(new User { Name = "Adam", Age = 10 });
...@@ -87,6 +90,7 @@ public async Task InsertCheckKeyAsync() ...@@ -87,6 +90,7 @@ public async Task InsertCheckKeyAsync()
{ {
using (var connection = GetOpenConnection()) using (var connection = GetOpenConnection())
{ {
connection.DeleteAll<User>();
(await connection.GetAsync<IUser>(3)).IsNull(); (await connection.GetAsync<IUser>(3)).IsNull();
User user = new User { Name = "Adamb", Age = 10 }; User user = new User { Name = "Adamb", Age = 10 };
int id = (int)await connection.InsertAsync(user); int id = (int)await connection.InsertAsync(user);
...@@ -98,6 +102,7 @@ public async Task BuilderSelectClauseAsync() ...@@ -98,6 +102,7 @@ public async Task BuilderSelectClauseAsync()
{ {
using (var connection = GetOpenConnection()) using (var connection = GetOpenConnection())
{ {
connection.DeleteAll<User>();
var rand = new Random(8675309); var rand = new Random(8675309);
var data = new List<User>(); var data = new List<User>();
for (int i = 0; i < 100; i++) for (int i = 0; i < 100; i++)
...@@ -134,6 +139,7 @@ public async Task BuilderTemplateWOCompositionAsync() ...@@ -134,6 +139,7 @@ public async Task BuilderTemplateWOCompositionAsync()
using (var connection = GetOpenConnection()) using (var connection = GetOpenConnection())
{ {
connection.DeleteAll<User>();
await connection.InsertAsync(new User { Age = 5, Name = "Testy McTestington" }); await connection.InsertAsync(new User { Age = 5, Name = "Testy McTestington" });
if ((await connection.QueryAsync<int>(template.RawSql, template.Parameters)).Single() != 1) if ((await connection.QueryAsync<int>(template.RawSql, template.Parameters)).Single() != 1)
...@@ -141,7 +147,7 @@ public async Task BuilderTemplateWOCompositionAsync() ...@@ -141,7 +147,7 @@ public async Task BuilderTemplateWOCompositionAsync()
} }
} }
public async Task GetAllAsync() public async Task InsertListAsync()
{ {
const int numberOfEntities = 100; const int numberOfEntities = 100;
...@@ -153,12 +159,32 @@ public async Task GetAllAsync() ...@@ -153,12 +159,32 @@ public async Task GetAllAsync()
{ {
connection.DeleteAll<User>(); connection.DeleteAll<User>();
var total = connection.Insert(users); var total = await connection.InsertAsync(users);
total.IsEqualTo(numberOfEntities);
users = connection.Query<User>("select * from users").ToList();
users.Count.IsEqualTo(numberOfEntities);
}
}
public async Task GetAllAsync()
{
const int numberOfEntities = 10000;
var users = new List<User>();
for (var i = 0; i < numberOfEntities; i++)
users.Add(new User { Name = "User " + i, Age = i });
using (var connection = GetOpenConnection())
{
connection.DeleteAll<User>();
var total = await connection.InsertAsync( users);
total.IsEqualTo(numberOfEntities); total.IsEqualTo(numberOfEntities);
users = (List<User>) await connection.GetAllAsync<User>(); users = (List<User>) await connection.GetAllAsync<User>();
users.Count.IsEqualTo(numberOfEntities); users.Count.IsEqualTo(numberOfEntities);
var iusers = await connection.GetAllAsync<IUser>(); var iusers = await connection.GetAllAsync<IUser>();
//iusers.Count.IsEqualTo(numberOfEntities); iusers.ToList().Count.IsEqualTo(numberOfEntities);
} }
} }
...@@ -166,6 +192,7 @@ public async Task InsertFieldWithReservedNameAsync() ...@@ -166,6 +192,7 @@ public async Task InsertFieldWithReservedNameAsync()
{ {
using (var connection = GetOpenConnection()) using (var connection = GetOpenConnection())
{ {
connection.DeleteAll<User>();
var id = await connection.InsertAsync(new Result() { Name = "Adam", Order = 1 }); var id = await connection.InsertAsync(new Result() { Name = "Adam", Order = 1 });
var result = await connection.GetAsync<Result>(id); var result = await connection.GetAsync<Result>(id);
...@@ -177,6 +204,7 @@ public async Task DeleteAllAsync() ...@@ -177,6 +204,7 @@ public async Task DeleteAllAsync()
{ {
using (var connection = GetOpenConnection()) using (var connection = GetOpenConnection())
{ {
connection.DeleteAll<User>();
var id1 = await connection.InsertAsync(new User() { Name = "Alice", Age = 32 }); var id1 = await connection.InsertAsync(new User() { Name = "Alice", Age = 32 });
var id2 = await connection.InsertAsync(new User() { Name = "Bob", Age = 33 }); var id2 = await connection.InsertAsync(new User() { Name = "Bob", Age = 33 });
await connection.DeleteAllAsync<User>(); await connection.DeleteAllAsync<User>();
......
...@@ -181,8 +181,6 @@ private static bool IsWriteable(PropertyInfo pi) ...@@ -181,8 +181,6 @@ private static bool IsWriteable(PropertyInfo pi)
if (!keys.Any()) if (!keys.Any())
throw new DataException("Get<T> only supports en entity with a [Key] property"); throw new DataException("Get<T> only supports en entity with a [Key] property");
var onlyKey = keys.First();
var name = GetTableName(type); var name = GetTableName(type);
// TODO: query information schema and only select fields that are both in information schema and underlying class / interface // TODO: query information schema and only select fields that are both in information schema and underlying class / interface
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment