diff --git a/Dapper.sln b/Dapper.sln
index e993c7a4..4aa75f10 100644
--- a/Dapper.sln
+++ b/Dapper.sln
@@ -16,7 +16,7 @@ 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}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapper.Contrib", "src\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
diff --git a/src/Dapper.Contrib/SqlMapperExtensions.Async.cs b/src/Dapper.Contrib/SqlMapperExtensions.Async.cs
index c93e39a4..336987eb 100644
--- a/src/Dapper.Contrib/SqlMapperExtensions.Async.cs
+++ b/src/Dapper.Contrib/SqlMapperExtensions.Async.cs
@@ -22,7 +22,8 @@ public static partial class SqlMapperExtensions
/// The transaction to run under, null (the default) if none
/// Number of seconds before command execution timeout
/// Entity of T
- public static async Task GetAsync(this IDbConnection connection, dynamic id, IDbTransaction transaction = null, int? commandTimeout = null) where T : class
+ public static async Task GetAsync(this IDbConnection connection, dynamic id,
+ IDbTransaction transaction = null, int? commandTimeout = null) where T : class
{
var type = typeof(T);
if (!GetQueries.TryGetValue(type.TypeHandle, out string sql))
@@ -38,9 +39,11 @@ public static async Task GetAsync(this IDbConnection connection, dynamic i
dynParams.Add("@id", id);
if (!type.IsInterface)
- return (await connection.QueryAsync(sql, dynParams, transaction, commandTimeout).ConfigureAwait(false)).FirstOrDefault();
+ return (await connection.QueryAsync(sql, dynParams, transaction, commandTimeout)
+ .ConfigureAwait(false)).FirstOrDefault();
- if (!((await connection.QueryAsync(sql, dynParams).ConfigureAwait(false)).FirstOrDefault() is IDictionary res))
+ if (!((await connection.QueryAsync(sql, dynParams).ConfigureAwait(false)).FirstOrDefault() is
+ IDictionary res))
{
return null;
}
@@ -51,7 +54,8 @@ public static async Task GetAsync(this IDbConnection connection, dynamic i
{
var val = res[property.Name];
if (val == null) continue;
- if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
+ if (property.PropertyType.IsGenericType &&
+ property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
var genericType = Nullable.GetUnderlyingType(property.PropertyType);
if (genericType != null) property.SetValue(obj, Convert.ChangeType(val, genericType), null);
@@ -62,7 +66,7 @@ public static async Task GetAsync(this IDbConnection connection, dynamic i
}
}
- ((IProxy)obj).IsDirty = false; //reset change tracking and return
+ ((IProxy)obj).IsDirty = false; //reset change tracking and return
return obj;
}
@@ -78,7 +82,8 @@ public static async Task GetAsync(this IDbConnection connection, dynamic i
/// The transaction to run under, null (the default) if none
/// Number of seconds before command execution timeout
/// Entity of T
- public static Task> GetAllAsync(this IDbConnection connection, IDbTransaction transaction = null, int? commandTimeout = null) where T : class
+ public static Task> GetAllAsync(this IDbConnection connection,
+ IDbTransaction transaction = null, int? commandTimeout = null) where T : class
{
var type = typeof(T);
var cacheType = typeof(List);
@@ -96,12 +101,15 @@ public static Task> GetAllAsync(this IDbConnection connection,
{
return connection.QueryAsync(sql, null, transaction, commandTimeout);
}
+
return GetAllAsyncImpl(connection, transaction, commandTimeout, sql, type);
}
- private static async Task> GetAllAsyncImpl(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string sql, Type type) where T : class
+ private static async Task> GetAllAsyncImpl(IDbConnection connection,
+ IDbTransaction transaction, int? commandTimeout, string sql, Type type) where T : class
{
- var result = await connection.QueryAsync(sql, transaction: transaction, commandTimeout: commandTimeout).ConfigureAwait(false);
+ var result = await connection.QueryAsync(sql, transaction: transaction, commandTimeout: commandTimeout)
+ .ConfigureAwait(false);
var list = new List();
foreach (IDictionary res in result)
{
@@ -110,7 +118,8 @@ private static async Task> GetAllAsyncImpl(IDbConnection conne
{
var val = res[property.Name];
if (val == null) continue;
- if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
+ if (property.PropertyType.IsGenericType &&
+ property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
var genericType = Nullable.GetUnderlyingType(property.PropertyType);
if (genericType != null) property.SetValue(obj, Convert.ChangeType(val, genericType), null);
@@ -120,9 +129,11 @@ private static async Task> GetAllAsyncImpl(IDbConnection conne
property.SetValue(obj, Convert.ChangeType(val, property.PropertyType), null);
}
}
- ((IProxy)obj).IsDirty = false; //reset change tracking and return
+
+ ((IProxy)obj).IsDirty = false; //reset change tracking and return
list.Add(obj);
}
+
return list;
}
@@ -136,7 +147,8 @@ private static async Task> GetAllAsyncImpl(IDbConnection conne
/// Number of seconds before command execution timeout
/// The specific ISqlAdapter to use, auto-detected based on connection if null
/// Identity of inserted entity
- public static Task InsertAsync(this IDbConnection connection, T entityToInsert, IDbTransaction transaction = null,
+ public static Task InsertAsync(this IDbConnection connection, T entityToInsert,
+ IDbTransaction transaction = null,
int? commandTimeout = null, ISqlAdapter sqlAdapter = null) where T : class
{
var type = typeof(T);
@@ -152,7 +164,8 @@ public static Task InsertAsync(this IDbConnection connection, T entityTo
{
var typeInfo = type.GetTypeInfo();
bool implementsGenericIEnumerableOrIsGenericIEnumerable =
- typeInfo.ImplementedInterfaces.Any(ti => ti.IsGenericType && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ||
+ typeInfo.ImplementedInterfaces.Any(ti =>
+ ti.IsGenericType && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ||
typeInfo.GetGenericTypeDefinition() == typeof(IEnumerable<>);
if (implementsGenericIEnumerableOrIsGenericIEnumerable)
@@ -167,7 +180,8 @@ public static Task InsertAsync(this IDbConnection connection, T entityTo
var allProperties = TypePropertiesCache(type);
var keyProperties = KeyPropertiesCache(type).ToList();
var computedProperties = ComputedPropertiesCache(type);
- var allPropertiesExceptKeyAndComputed = allProperties.Except(keyProperties.Union(computedProperties)).ToList();
+ var allPropertiesExceptKeyAndComputed =
+ allProperties.Except(keyProperties.Union(computedProperties)).ToList();
for (var i = 0; i < allPropertiesExceptKeyAndComputed.Count; i++)
{
@@ -186,7 +200,7 @@ public static Task InsertAsync(this IDbConnection connection, T entityTo
sbParameterList.Append(", ");
}
- if (!isList) //single entity
+ if (!isList) //single entity
{
return sqlAdapter.InsertAsync(connection, transaction, commandTimeout, name, sbColumnList.ToString(),
sbParameterList.ToString(), keyProperties, entityToInsert);
@@ -206,7 +220,8 @@ public static Task InsertAsync(this IDbConnection connection, T entityTo
/// The transaction to run under, null (the default) if none
/// Number of seconds before command execution timeout
/// true if updated, false if not found or not modified (tracked entities)
- public static async Task UpdateAsync(this IDbConnection connection, T entityToUpdate, IDbTransaction transaction = null, int? commandTimeout = null) where T : class
+ public static async Task UpdateAsync(this IDbConnection connection, T entityToUpdate,
+ IDbTransaction transaction = null, int? commandTimeout = null) where T : class
{
if ((entityToUpdate is IProxy proxy) && !proxy.IsDirty)
{
@@ -223,7 +238,8 @@ public static async Task UpdateAsync(this IDbConnection connection, T e
{
var typeInfo = type.GetTypeInfo();
bool implementsGenericIEnumerableOrIsGenericIEnumerable =
- typeInfo.ImplementedInterfaces.Any(ti => ti.IsGenericType && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ||
+ typeInfo.ImplementedInterfaces.Any(ti =>
+ ti.IsGenericType && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ||
typeInfo.GetGenericTypeDefinition() == typeof(IEnumerable<>);
if (implementsGenericIEnumerableOrIsGenericIEnumerable)
@@ -256,6 +272,7 @@ public static async Task UpdateAsync(this IDbConnection connection, T e
if (i < nonIdProps.Count - 1)
sb.Append(", ");
}
+
sb.Append(" where ");
for (var i = 0; i < keyProperties.Count; i++)
{
@@ -264,7 +281,73 @@ public static async Task UpdateAsync(this IDbConnection connection, T e
if (i < keyProperties.Count - 1)
sb.Append(" and ");
}
- var updated = await connection.ExecuteAsync(sb.ToString(), entityToUpdate, commandTimeout: commandTimeout, transaction: transaction).ConfigureAwait(false);
+
+ var updated = await connection
+ .ExecuteAsync(sb.ToString(), entityToUpdate, commandTimeout: commandTimeout, transaction: transaction)
+ .ConfigureAwait(false);
+ return updated > 0;
+ }
+
+ ///
+ /// Use dynamic parameters to update entity in table "Ts" asynchronously using Task, checks if the entity is modified if the entity is tracked by the Get() extension.
+ ///
+ /// Type to be updated
+ /// Open SqlConnection
+ /// parameters,must have at least one [Key] or [ExplicitKey] property
+ /// The transaction to run under, null (the default) if none
+ /// Number of seconds before command execution timeout
+ /// true if updated, false if not found or not modified (tracked entities)
+ public static async Task DynamicParametersUpdateAsync(this IDbConnection connection, object parameters,
+ IDbTransaction transaction = null, int? commandTimeout = null) where T : class
+ {
+ var type = typeof(T);
+
+ var keyProperties = KeyPropertiesCache(type).ToList();
+ var explicitKeyProperties = ExplicitKeyPropertiesCache(type);
+ if (keyProperties.Count == 0 && explicitKeyProperties.Count == 0)
+ throw new ArgumentException("Entity must have at least one [Key] or [ExplicitKey] property");
+ keyProperties.AddRange(explicitKeyProperties);
+
+ var props = parameters.GetType().GetProperties();
+
+ var paramKeyProperties = props.Where(x =>
+ keyProperties.Any(p => p.Name.Equals(x.Name, StringComparison.CurrentCultureIgnoreCase))).ToList();
+
+
+ if (!paramKeyProperties.Any())
+ {
+ throw new ArgumentException("Parameters must have at least one [Key] or [ExplicitKey] property");
+ }
+
+
+ var name = GetTableName(type);
+
+ var sb = new StringBuilder();
+ sb.AppendFormat("update {0} set ", name);
+
+ var computedProperties = ComputedPropertiesCache(type);
+ var nonIdProps = props.Where(x=>!keyProperties.Union(computedProperties).Any(y=>y.Name.Equals(x.Name, StringComparison.CurrentCultureIgnoreCase))).ToList();
+
+ var adapter = GetFormatter(connection);
+
+ for (var i = 0; i < nonIdProps.Count; i++)
+ {
+ var property = nonIdProps[i];
+ adapter.AppendColumnNameEqualsValue(sb, property.Name);
+ if (i < nonIdProps.Count - 1)
+ sb.Append(", ");
+ }
+
+ sb.Append(" where ");
+ for (var i = 0; i < paramKeyProperties.Count(); i++)
+ {
+ var property = paramKeyProperties[i];
+ adapter.AppendColumnNameEqualsValue(sb, property.Name);
+ if (i < paramKeyProperties.Count - 1)
+ sb.Append(" and ");
+ }
+
+ var updated = await connection.ExecuteAsync(sb.ToString(), parameters, transaction, commandTimeout);
return updated > 0;
}
@@ -277,7 +360,8 @@ public static async Task UpdateAsync(this IDbConnection connection, T e
/// The transaction to run under, null (the default) if none
/// Number of seconds before command execution timeout
/// true if deleted, false if not found
- public static async Task DeleteAsync(this IDbConnection connection, T entityToDelete, IDbTransaction transaction = null, int? commandTimeout = null) where T : class
+ public static async Task DeleteAsync(this IDbConnection connection, T entityToDelete,
+ IDbTransaction transaction = null, int? commandTimeout = null) where T : class
{
if (entityToDelete == null)
throw new ArgumentException("Cannot Delete null Object", nameof(entityToDelete));
@@ -292,7 +376,8 @@ public static async Task DeleteAsync(this IDbConnection connection, T e
{
var typeInfo = type.GetTypeInfo();
bool implementsGenericIEnumerableOrIsGenericIEnumerable =
- typeInfo.ImplementedInterfaces.Any(ti => ti.IsGenericType && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ||
+ typeInfo.ImplementedInterfaces.Any(ti =>
+ ti.IsGenericType && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ||
typeInfo.GetGenericTypeDefinition() == typeof(IEnumerable<>);
if (implementsGenericIEnumerableOrIsGenericIEnumerable)
@@ -321,7 +406,9 @@ public static async Task DeleteAsync(this IDbConnection connection, T e
if (i < allKeyProperties.Count - 1)
sb.Append(" AND ");
}
- var deleted = await connection.ExecuteAsync(sb.ToString(), entityToDelete, transaction, commandTimeout).ConfigureAwait(false);
+
+ var deleted = await connection.ExecuteAsync(sb.ToString(), entityToDelete, transaction, commandTimeout)
+ .ConfigureAwait(false);
return deleted > 0;
}
@@ -333,11 +420,13 @@ public static async Task DeleteAsync(this IDbConnection connection, T e
/// The transaction to run under, null (the default) if none
/// Number of seconds before command execution timeout
/// true if deleted, false if none found
- public static async Task DeleteAllAsync(this IDbConnection connection, IDbTransaction transaction = null, int? commandTimeout = null) where T : class
+ public static async Task DeleteAllAsync(this IDbConnection connection,
+ IDbTransaction transaction = null, int? commandTimeout = null) where T : class
{
var type = typeof(T);
var statement = "DELETE FROM " + GetTableName(type);
- var deleted = await connection.ExecuteAsync(statement, null, transaction, commandTimeout).ConfigureAwait(false);
+ var deleted = await connection.ExecuteAsync(statement, null, transaction, commandTimeout)
+ .ConfigureAwait(false);
return deleted > 0;
}
}
@@ -357,7 +446,8 @@ public partial interface ISqlAdapter
/// The key columns in this table.
/// The entity to insert.
/// The Id of the row created.
- 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, IEnumerable keyProperties, object entityToInsert);
}
public partial class SqlServerAdapter
@@ -374,10 +464,13 @@ public partial class SqlServerAdapter
/// The key columns in this table.
/// The entity to insert.
/// The Id of the row created.
- 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, IEnumerable keyProperties,
+ object entityToInsert)
{
var cmd = $"INSERT INTO {tableName} ({columnList}) values ({parameterList}); SELECT SCOPE_IDENTITY() id";
- var multi = await connection.QueryMultipleAsync(cmd, entityToInsert, transaction, commandTimeout).ConfigureAwait(false);
+ var multi = await connection.QueryMultipleAsync(cmd, entityToInsert, transaction, commandTimeout)
+ .ConfigureAwait(false);
var first = await multi.ReadFirstOrDefaultAsync().ConfigureAwait(false);
if (first == null || first.id == null) return 0;
@@ -407,11 +500,15 @@ public partial class SqlCeServerAdapter
/// The key columns in this table.
/// The entity to insert.
/// The Id of the row created.
- 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, IEnumerable keyProperties,
+ object entityToInsert)
{
var cmd = $"INSERT INTO {tableName} ({columnList}) VALUES ({parameterList})";
await connection.ExecuteAsync(cmd, entityToInsert, transaction, commandTimeout).ConfigureAwait(false);
- var r = (await connection.QueryAsync("SELECT @@IDENTITY id", transaction: transaction, commandTimeout: commandTimeout).ConfigureAwait(false)).ToList();
+ var r = (await connection
+ .QueryAsync("SELECT @@IDENTITY id", transaction: transaction, commandTimeout: commandTimeout)
+ .ConfigureAwait(false)).ToList();
if (r[0] == null || r[0].id == null) return 0;
var id = (int)r[0].id;
@@ -440,12 +537,15 @@ public partial class MySqlAdapter
/// The key columns in this table.
/// The entity to insert.
/// The Id of the row created.
- public async Task InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName,
+ public async Task InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout,
+ string tableName,
string columnList, string parameterList, IEnumerable keyProperties, object entityToInsert)
{
var cmd = $"INSERT INTO {tableName} ({columnList}) VALUES ({parameterList})";
await connection.ExecuteAsync(cmd, entityToInsert, transaction, commandTimeout).ConfigureAwait(false);
- var r = await connection.QueryAsync("SELECT LAST_INSERT_ID() id", transaction: transaction, commandTimeout: commandTimeout).ConfigureAwait(false);
+ var r = await connection
+ .QueryAsync("SELECT LAST_INSERT_ID() id", transaction: transaction, commandTimeout: commandTimeout)
+ .ConfigureAwait(false);
var id = r.First().id;
if (id == null) return 0;
@@ -473,7 +573,9 @@ public partial class PostgresAdapter
/// The key columns in this table.
/// The entity to insert.
/// The Id of the row created.
- 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, IEnumerable keyProperties,
+ object entityToInsert)
{
var sb = new StringBuilder();
sb.AppendFormat("INSERT INTO {0} ({1}) VALUES ({2})", tableName, columnList, parameterList);
@@ -497,7 +599,8 @@ public async Task InsertAsync(IDbConnection connection, IDbTransaction tran
}
}
- var results = await connection.QueryAsync(sb.ToString(), entityToInsert, transaction, commandTimeout).ConfigureAwait(false);
+ var results = await connection.QueryAsync(sb.ToString(), entityToInsert, transaction, commandTimeout)
+ .ConfigureAwait(false);
// Return the key by assigning the corresponding property in the object - by product is that it supports compound primary keys
var id = 0;
@@ -508,6 +611,7 @@ public async Task InsertAsync(IDbConnection connection, IDbTransaction tran
if (id == 0)
id = Convert.ToInt32(value);
}
+
return id;
}
}
@@ -526,10 +630,13 @@ public partial class SQLiteAdapter
/// The key columns in this table.
/// The entity to insert.
/// The Id of the row created.
- 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, IEnumerable 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).ConfigureAwait(false);
+ var multi = await connection.QueryMultipleAsync(cmd, entityToInsert, transaction, commandTimeout)
+ .ConfigureAwait(false);
var id = (int)(await multi.ReadFirstAsync().ConfigureAwait(false)).id;
var pi = keyProperties as PropertyInfo[] ?? keyProperties.ToArray();
@@ -556,14 +663,17 @@ public partial class FbAdapter
/// The key columns in this table.
/// The entity to insert.
/// The Id of the row created.
- 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, IEnumerable keyProperties,
+ object entityToInsert)
{
var cmd = $"insert into {tableName} ({columnList}) values ({parameterList})";
await connection.ExecuteAsync(cmd, entityToInsert, transaction, commandTimeout).ConfigureAwait(false);
var propertyInfos = keyProperties as PropertyInfo[] ?? keyProperties.ToArray();
var keyName = propertyInfos[0].Name;
- var r = await connection.QueryAsync($"SELECT FIRST 1 {keyName} ID FROM {tableName} ORDER BY {keyName} DESC", transaction: transaction, commandTimeout: commandTimeout).ConfigureAwait(false);
+ var r = await connection.QueryAsync($"SELECT FIRST 1 {keyName} ID FROM {tableName} ORDER BY {keyName} DESC",
+ transaction: transaction, commandTimeout: commandTimeout).ConfigureAwait(false);
var id = r.First().ID;
if (id == null) return 0;
diff --git a/tests/Dapper.Tests.Contrib/TestSuite.Async.cs b/tests/Dapper.Tests.Contrib/TestSuite.Async.cs
index fcd11802..f4225c74 100644
--- a/tests/Dapper.Tests.Contrib/TestSuite.Async.cs
+++ b/tests/Dapper.Tests.Contrib/TestSuite.Async.cs
@@ -204,7 +204,34 @@ public async Task InsertGetUpdateAsync()
Assert.True(await connection.InsertAsync(new User { Name = "Adam", Age = 10 }).ConfigureAwait(false) > originalCount + 1);
}
}
-
+ [Fact]
+ public async Task DynamicParametersUpdateAsync()
+ {
+ using (var connection = GetOpenConnection())
+ {
+ Assert.Null(await connection.GetAsync(30).ConfigureAwait(false));
+
+ var id = await connection.InsertAsync(new User { Name = "Adam", Age = 10 }).ConfigureAwait(false);
+
+ var user = await connection.GetAsync(id).ConfigureAwait(false);
+
+ var parameters1 = new { id=user.Id,name="Bob"};
+ Assert.True(await connection.DynamicParametersUpdateAsync(parameters1).ConfigureAwait(false));
+ Assert.Equal("Bob", (await connection.GetAsync(id).ConfigureAwait(false)).Name);
+ Assert.Equal(10, (await connection.GetAsync(id).ConfigureAwait(false)).Age);
+
+ var parameters2 = new { id=user.Id,age=20};
+
+ Assert.True(await connection.DynamicParametersUpdateAsync(parameters2).ConfigureAwait(false));
+ Assert.Equal("Bob", (await connection.GetAsync(id).ConfigureAwait(false)).Name);
+ Assert.Equal(20, (await connection.GetAsync(id).ConfigureAwait(false)).Age);
+
+ var parameters3 = new { id=-1,age=20};
+
+ Assert.False(await connection.DynamicParametersUpdateAsync(parameters3).ConfigureAwait(false));
+
+ }
+ }
[Fact]
public async Task InsertCheckKeyAsync()
{