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
public static partial class SqlMapperExtensions
{
/// <summary>
/// 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.
......@@ -41,7 +41,6 @@ public static partial class SqlMapperExtensions
var name = GetTableName(type);
// TODO: pluralizer
// 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";
GetQueries[type.TypeHandle] = sql;
......@@ -50,29 +49,25 @@ public static partial class SqlMapperExtensions
var dynParms = new DynamicParameters();
dynParms.Add("@id", id);
T obj;
if (type.IsInterface)
{
var res = (await connection.QueryAsync<dynamic>(sql, dynParms).ConfigureAwait(false)).FirstOrDefault() as IDictionary<string, object>;
if (!type.IsInterface)
return (await connection.QueryAsync<T>(sql, dynParms, transaction, commandTimeout).ConfigureAwait(false)).FirstOrDefault();
if (res == null)
return null;
var res = (await connection.QueryAsync<dynamic>(sql, dynParms).ConfigureAwait(false)).FirstOrDefault() as IDictionary<string, object>;
obj = ProxyGenerator.GetInterfaceProxy<T>();
if (res == null)
return null;
foreach (var property in TypePropertiesCache(type))
{
var val = res[property.Name];
property.SetValue(obj, val, null);
}
var obj = ProxyGenerator.GetInterfaceProxy<T>();
((IProxy)obj).IsDirty = false; //reset change tracking and return
}
else
foreach (var property in TypePropertiesCache(type))
{
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;
}
......@@ -99,8 +94,6 @@ public static partial class SqlMapperExtensions
if (!keys.Any())
throw new DataException("Get<T> only supports en entity with a [Key] property");
var onlyKey = keys.First();
var name = GetTableName(type);
// 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
var result = await connection.QueryAsync(sql);
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>();
foreach (var property in TypePropertiesCache(type))
{
......@@ -126,8 +118,7 @@ public static partial class SqlMapperExtensions
}
((IProxy)obj).IsDirty = false; //reset change tracking and return
list.Add(obj);
});
}
return list;
}
......@@ -138,9 +129,18 @@ public static partial class SqlMapperExtensions
/// <param name="connection">Open SqlConnection</param>
/// <param name="entityToInsert">Entity to insert</param>
/// <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);
if (type.IsArray || type.IsGenericType)
{
isList = true;
type = type.GetGenericArguments()[0];
}
var name = GetTableName(type);
var sbColumnList = new StringBuilder(null);
var allProperties = TypePropertiesCache(type);
......@@ -164,9 +164,17 @@ public static partial class SqlMapperExtensions
if (i < allPropertiesExceptKeyAndComputed.Count() - 1)
sbParameterList.Append(", ");
}
var adapter = GetFormatter(connection);
return adapter.InsertAsync(connection, transaction, commandTimeout, name, sbColumnList.ToString(),
sbParameterList.ToString(), keyProperties, entityToInsert);
if (!isList) //single entity
{
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>
......
......@@ -28,6 +28,7 @@ public async Task TableNameAsync()
{
using (var connection = GetOpenConnection())
{
connection.DeleteAll<User>();
// tests against "Automobiles" table (Table attribute)
await connection.InsertAsync(new Car { Name = "Volvo" });
(await connection.GetAsync<Car>(1)).Name.IsEqualTo("Volvo");
......@@ -42,6 +43,7 @@ public async Task TestSimpleGetAsync()
{
using (var connection = GetOpenConnection())
{
connection.DeleteAll<User>();
var id = await connection.InsertAsync(new User { Name = "Adama", Age = 10 });
var user = await connection.GetAsync<User>(id);
user.Id.IsEqualTo((int)id);
......@@ -54,6 +56,7 @@ public async Task InsertGetUpdateAsync()
{
using (var connection = GetOpenConnection())
{
connection.DeleteAll<User>();
(await connection.GetAsync<User>(3)).IsNull();
var id = await connection.InsertAsync(new User { Name = "Adam", Age = 10 });
......@@ -87,6 +90,7 @@ public async Task InsertCheckKeyAsync()
{
using (var connection = GetOpenConnection())
{
connection.DeleteAll<User>();
(await connection.GetAsync<IUser>(3)).IsNull();
User user = new User { Name = "Adamb", Age = 10 };
int id = (int)await connection.InsertAsync(user);
......@@ -98,6 +102,7 @@ public async Task BuilderSelectClauseAsync()
{
using (var connection = GetOpenConnection())
{
connection.DeleteAll<User>();
var rand = new Random(8675309);
var data = new List<User>();
for (int i = 0; i < 100; i++)
......@@ -134,6 +139,7 @@ public async Task BuilderTemplateWOCompositionAsync()
using (var connection = GetOpenConnection())
{
connection.DeleteAll<User>();
await connection.InsertAsync(new User { Age = 5, Name = "Testy McTestington" });
if ((await connection.QueryAsync<int>(template.RawSql, template.Parameters)).Single() != 1)
......@@ -141,7 +147,7 @@ public async Task BuilderTemplateWOCompositionAsync()
}
}
public async Task GetAllAsync()
public async Task InsertListAsync()
{
const int numberOfEntities = 100;
......@@ -153,12 +159,32 @@ public async Task GetAllAsync()
{
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);
users = (List<User>) await connection.GetAllAsync<User>();
users.Count.IsEqualTo(numberOfEntities);
var iusers = await connection.GetAllAsync<IUser>();
//iusers.Count.IsEqualTo(numberOfEntities);
iusers.ToList().Count.IsEqualTo(numberOfEntities);
}
}
......@@ -166,6 +192,7 @@ public async Task InsertFieldWithReservedNameAsync()
{
using (var connection = GetOpenConnection())
{
connection.DeleteAll<User>();
var id = await connection.InsertAsync(new Result() { Name = "Adam", Order = 1 });
var result = await connection.GetAsync<Result>(id);
......@@ -177,6 +204,7 @@ public async Task DeleteAllAsync()
{
using (var connection = GetOpenConnection())
{
connection.DeleteAll<User>();
var id1 = await connection.InsertAsync(new User() { Name = "Alice", Age = 32 });
var id2 = await connection.InsertAsync(new User() { Name = "Bob", Age = 33 });
await connection.DeleteAllAsync<User>();
......
......@@ -181,8 +181,6 @@ private static bool IsWriteable(PropertyInfo pi)
if (!keys.Any())
throw new DataException("Get<T> only supports en entity with a [Key] property");
var onlyKey = keys.First();
var name = GetTableName(type);
// 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