Commit c28a87ff authored by Henk Mollema's avatar Henk Mollema

Utilize C# 6 features

- Expression bodies
- Auto-properties (also get-only properties)
- Null propagation
- `nameof` operator
- String interpolation
- Dictionary initializer
- await in finally clause
parent 295d1ad2
...@@ -18,7 +18,8 @@ ...@@ -18,7 +18,8 @@
#endif #endif
namespace Dapper namespace Dapper
{ /// <summary> {
/// <summary>
/// Represents the key aspects of a sql operation /// Represents the key aspects of a sql operation
/// </summary> /// </summary>
public struct CommandDefinition public struct CommandDefinition
...@@ -34,61 +35,56 @@ internal static CommandDefinition ForCallback(object parameters) ...@@ -34,61 +35,56 @@ internal static CommandDefinition ForCallback(object parameters)
return default(CommandDefinition); return default(CommandDefinition);
} }
} }
private readonly string commandText;
private readonly object parameters;
private readonly IDbTransaction transaction;
private readonly int? commandTimeout;
private readonly CommandType? commandType;
private readonly CommandFlags flags;
internal void OnCompleted() internal void OnCompleted()
{ {
if (parameters is SqlMapper.IParameterCallbacks) (Parameters as SqlMapper.IParameterCallbacks)?.OnCompleted();
{
((SqlMapper.IParameterCallbacks)parameters).OnCompleted();
}
} }
/// <summary> /// <summary>
/// The command (sql or a stored-procedure name) to execute /// The command (sql or a stored-procedure name) to execute
/// </summary> /// </summary>
public string CommandText { get { return commandText; } } public string CommandText { get; }
/// <summary> /// <summary>
/// The parameters associated with the command /// The parameters associated with the command
/// </summary> /// </summary>
public object Parameters { get { return parameters; } } public object Parameters { get; }
/// <summary> /// <summary>
/// The active transaction for the command /// The active transaction for the command
/// </summary> /// </summary>
public IDbTransaction Transaction { get { return transaction; } } public IDbTransaction Transaction { get; }
/// <summary> /// <summary>
/// The effective timeout for the command /// The effective timeout for the command
/// </summary> /// </summary>
public int? CommandTimeout { get { return commandTimeout; } } public int? CommandTimeout { get; }
/// <summary> /// <summary>
/// The type of command that the command-text represents /// The type of command that the command-text represents
/// </summary> /// </summary>
public CommandType? CommandType { get { return commandType; } } public CommandType? CommandType { get; }
/// <summary> /// <summary>
/// Should data be buffered before returning? /// Should data be buffered before returning?
/// </summary> /// </summary>
public bool Buffered { get { return (flags & CommandFlags.Buffered) != 0; } } public bool Buffered => (Flags & CommandFlags.Buffered) != 0;
/// <summary> /// <summary>
/// Should the plan for this query be cached? /// Should the plan for this query be cached?
/// </summary> /// </summary>
internal bool AddToCache { get { return (flags & CommandFlags.NoCache) == 0; } } internal bool AddToCache => (Flags & CommandFlags.NoCache) == 0;
/// <summary> /// <summary>
/// Additional state flags against this command /// Additional state flags against this command
/// </summary> /// </summary>
public CommandFlags Flags { get { return flags; } } public CommandFlags Flags { get; }
/// <summary> /// <summary>
/// Can async queries be pipelined? /// Can async queries be pipelined?
/// </summary> /// </summary>
public bool Pipelined { get { return (flags & CommandFlags.Pipelined) != 0; } } public bool Pipelined => (Flags & CommandFlags.Pipelined) != 0;
/// <summary> /// <summary>
/// Initialize the command definition /// Initialize the command definition
...@@ -100,59 +96,58 @@ internal void OnCompleted() ...@@ -100,59 +96,58 @@ internal void OnCompleted()
#endif #endif
) )
{ {
this.commandText = commandText; CommandText = commandText;
this.parameters = parameters; Parameters = parameters;
this.transaction = transaction; Transaction = transaction;
this.commandTimeout = commandTimeout; CommandTimeout = commandTimeout;
this.commandType = commandType; CommandType = commandType;
this.flags = flags; Flags = flags;
#if ASYNC #if ASYNC
this.cancellationToken = cancellationToken; CancellationToken = cancellationToken;
#endif #endif
} }
private CommandDefinition(object parameters) : this() private CommandDefinition(object parameters) : this()
{ {
this.parameters = parameters; Parameters = parameters;
} }
#if ASYNC #if ASYNC
private readonly CancellationToken cancellationToken;
/// <summary> /// <summary>
/// For asynchronous operations, the cancellation-token /// For asynchronous operations, the cancellation-token
/// </summary> /// </summary>
public CancellationToken CancellationToken { get { return cancellationToken; } } public CancellationToken CancellationToken { get; }
#endif #endif
internal IDbCommand SetupCommand(IDbConnection cnn, Action<IDbCommand, object> paramReader) internal IDbCommand SetupCommand(IDbConnection cnn, Action<IDbCommand, object> paramReader)
{ {
var cmd = cnn.CreateCommand(); var cmd = cnn.CreateCommand();
var init = GetInit(cmd.GetType()); var init = GetInit(cmd.GetType());
if (init != null) init(cmd); init?.Invoke(cmd);
if (transaction != null) if (Transaction != null)
cmd.Transaction = transaction; cmd.Transaction = Transaction;
cmd.CommandText = commandText; cmd.CommandText = CommandText;
if (commandTimeout.HasValue) if (CommandTimeout.HasValue)
{ {
cmd.CommandTimeout = commandTimeout.Value; cmd.CommandTimeout = CommandTimeout.Value;
} }
else if (SqlMapper.Settings.CommandTimeout.HasValue) else if (SqlMapper.Settings.CommandTimeout.HasValue)
{ {
cmd.CommandTimeout = SqlMapper.Settings.CommandTimeout.Value; cmd.CommandTimeout = SqlMapper.Settings.CommandTimeout.Value;
} }
if (commandType.HasValue) if (CommandType.HasValue)
cmd.CommandType = commandType.Value; cmd.CommandType = CommandType.Value;
if (paramReader != null) paramReader?.Invoke(cmd, Parameters);
{
paramReader(cmd, parameters);
}
return cmd; return cmd;
} }
static SqlMapper.Link<Type, Action<IDbCommand>> commandInitCache; private static SqlMapper.Link<Type, Action<IDbCommand>> commandInitCache;
static Action<IDbCommand> GetInit(Type commandType)
private static Action<IDbCommand> GetInit(Type commandType)
{ {
if (commandType == null) return null; // GIGO if (commandType == null)
return null; // GIGO
Action<IDbCommand> action; Action<IDbCommand> action;
if (SqlMapper.Link<Type, Action<IDbCommand>>.TryGet(commandInitCache, commandType, out action)) if (SqlMapper.Link<Type, Action<IDbCommand>>.TryGet(commandInitCache, commandType, out action))
{ {
...@@ -190,7 +185,8 @@ static Action<IDbCommand> GetInit(Type commandType) ...@@ -190,7 +185,8 @@ static Action<IDbCommand> GetInit(Type commandType)
SqlMapper.Link<Type, Action<IDbCommand>>.TryAdd(ref commandInitCache, commandType, ref action); SqlMapper.Link<Type, Action<IDbCommand>>.TryAdd(ref commandInitCache, commandType, ref action);
return action; return action;
} }
static MethodInfo GetBasicPropertySetter(Type declaringType, string name, Type expectedType)
private static MethodInfo GetBasicPropertySetter(Type declaringType, string name, Type expectedType)
{ {
var prop = declaringType.GetProperty(name, BindingFlags.Public | BindingFlags.Instance); var prop = declaringType.GetProperty(name, BindingFlags.Public | BindingFlags.Instance);
ParameterInfo[] indexers; ParameterInfo[] indexers;
......
...@@ -20,10 +20,10 @@ public sealed class CustomPropertyTypeMap : SqlMapper.ITypeMap ...@@ -20,10 +20,10 @@ public sealed class CustomPropertyTypeMap : SqlMapper.ITypeMap
public CustomPropertyTypeMap(Type type, Func<Type, string, PropertyInfo> propertySelector) public CustomPropertyTypeMap(Type type, Func<Type, string, PropertyInfo> propertySelector)
{ {
if (type == null) if (type == null)
throw new ArgumentNullException("type"); throw new ArgumentNullException(nameof(type));
if (propertySelector == null) if (propertySelector == null)
throw new ArgumentNullException("propertySelector"); throw new ArgumentNullException(nameof(propertySelector));
_type = type; _type = type;
_propertySelector = propertySelector; _propertySelector = propertySelector;
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#if !DNXCORE50 #if !DNXCORE50
namespace Dapper namespace Dapper
{ {
sealed class DataTableHandler : Dapper.SqlMapper.ITypeHandler sealed class DataTableHandler : SqlMapper.ITypeHandler
{ {
public object Parse(Type destinationType, object value) public object Parse(Type destinationType, object value)
{ {
......
...@@ -19,7 +19,7 @@ namespace Dapper ...@@ -19,7 +19,7 @@ namespace Dapper
/// <summary> /// <summary>
/// This class represents a SQL string, it can be used if you need to denote your parameter is a Char vs VarChar vs nVarChar vs nChar /// This class represents a SQL string, it can be used if you need to denote your parameter is a Char vs VarChar vs nVarChar vs nChar
/// </summary> /// </summary>
public sealed class DbString : Dapper.SqlMapper.ICustomQueryParameter public sealed class DbString : SqlMapper.ICustomQueryParameter
{ {
/// <summary> /// <summary>
/// Default value for IsAnsi. /// Default value for IsAnsi.
......
...@@ -11,7 +11,6 @@ namespace Dapper ...@@ -11,7 +11,6 @@ namespace Dapper
sealed class DefaultTypeMap : SqlMapper.ITypeMap sealed class DefaultTypeMap : SqlMapper.ITypeMap
{ {
private readonly List<FieldInfo> _fields; private readonly List<FieldInfo> _fields;
private readonly List<PropertyInfo> _properties;
private readonly Type _type; private readonly Type _type;
/// <summary> /// <summary>
...@@ -21,10 +20,10 @@ sealed class DefaultTypeMap : SqlMapper.ITypeMap ...@@ -21,10 +20,10 @@ sealed class DefaultTypeMap : SqlMapper.ITypeMap
public DefaultTypeMap(Type type) public DefaultTypeMap(Type type)
{ {
if (type == null) if (type == null)
throw new ArgumentNullException("type"); throw new ArgumentNullException(nameof(type));
_fields = GetSettableFields(type); _fields = GetSettableFields(type);
_properties = GetSettableProps(type); Properties = GetSettableProps(type);
_type = type; _type = type;
} }
#if DNXCORE50 #if DNXCORE50
...@@ -184,12 +183,6 @@ public SqlMapper.IMemberMap GetMember(string columnName) ...@@ -184,12 +183,6 @@ public SqlMapper.IMemberMap GetMember(string columnName)
/// </summary> /// </summary>
public static bool MatchNamesWithUnderscores { get; set; } public static bool MatchNamesWithUnderscores { get; set; }
public List<PropertyInfo> Properties public List<PropertyInfo> Properties { get; }
{
get
{
return _properties;
}
}
} }
} }
...@@ -246,7 +246,7 @@ protected void AddParameters(IDbCommand command, SqlMapper.Identity identity) ...@@ -246,7 +246,7 @@ protected void AddParameters(IDbCommand command, SqlMapper.Identity identity)
{ {
((SqlMapper.ICustomQueryParameter)val).AddParameter(command, name); ((SqlMapper.ICustomQueryParameter)val).AddParameter(command, name);
} }
else if (dbType == DynamicParameters.EnumerableMultiParameter) else if (dbType == EnumerableMultiParameter)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
SqlMapper.PackListParameters(command, name, val); SqlMapper.PackListParameters(command, name, val);
...@@ -276,13 +276,10 @@ protected void AddParameters(IDbCommand command, SqlMapper.Identity identity) ...@@ -276,13 +276,10 @@ protected void AddParameters(IDbCommand command, SqlMapper.Identity identity)
p.DbType = dbType.Value; p.DbType = dbType.Value;
} }
var s = val as string; var s = val as string;
if (s != null) if (s?.Length <= DbString.DefaultLength)
{
if (s.Length <= DbString.DefaultLength)
{ {
p.Size = DbString.DefaultLength; p.Size = DbString.DefaultLength;
} }
}
if (param.Size != null) p.Size = param.Size.Value; if (param.Size != null) p.Size = param.Size.Value;
if (param.Precision != null) p.Precision = param.Precision.Value; if (param.Precision != null) p.Precision = param.Precision.Value;
if (param.Scale != null) p.Scale = param.Scale.Value; if (param.Scale != null) p.Scale = param.Scale.Value;
...@@ -385,11 +382,11 @@ public DynamicParameters Output<T>(T target, Expression<Func<T, object>> express ...@@ -385,11 +382,11 @@ public DynamicParameters Output<T>(T target, Expression<Func<T, object>> express
{ {
// Insert the names in the right order so expression // Insert the names in the right order so expression
// "Post.Author.Name" becomes parameter "PostAuthorName" // "Post.Author.Name" becomes parameter "PostAuthorName"
names.Insert(0, diving.Member.Name); names.Insert(0, diving?.Member.Name);
chain.Insert(0, diving); chain.Insert(0, diving);
var constant = diving.Expression as ParameterExpression; var constant = diving?.Expression as ParameterExpression;
diving = diving.Expression as MemberExpression; diving = diving?.Expression as MemberExpression;
if (constant != null && if (constant != null &&
constant.Type == typeof(T)) constant.Type == typeof(T))
...@@ -423,7 +420,7 @@ public DynamicParameters Output<T>(T target, Expression<Func<T, object>> express ...@@ -423,7 +420,7 @@ public DynamicParameters Output<T>(T target, Expression<Func<T, object>> express
if (setter != null) goto MAKECALLBACK; if (setter != null) goto MAKECALLBACK;
// Come on let's build a method, let's build it, let's build it now! // Come on let's build a method, let's build it, let's build it now!
var dm = new DynamicMethod(string.Format("ExpressionParam{0}", Guid.NewGuid()), null, new[] { typeof(object), this.GetType() }, true); var dm = new DynamicMethod($"ExpressionParam{Guid.NewGuid()}", null, new[] { typeof(object), GetType() }, true);
var il = dm.GetILGenerator(); var il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0); // [object] il.Emit(OpCodes.Ldarg_0); // [object]
...@@ -446,7 +443,7 @@ public DynamicParameters Output<T>(T target, Expression<Func<T, object>> express ...@@ -446,7 +443,7 @@ public DynamicParameters Output<T>(T target, Expression<Func<T, object>> express
} }
} }
var paramGetter = this.GetType().GetMethod("Get", new Type[] { typeof(string) }).MakeGenericMethod(lastMemberAccess.Type); var paramGetter = GetType().GetMethod("Get", new Type[] { typeof(string) }).MakeGenericMethod(lastMemberAccess.Type);
il.Emit(OpCodes.Ldarg_1); // [target] [DynamicParameters] il.Emit(OpCodes.Ldarg_1); // [target] [DynamicParameters]
il.Emit(OpCodes.Ldstr, dynamicParamName); // [target] [DynamicParameters] [ParamName] il.Emit(OpCodes.Ldstr, dynamicParamName); // [target] [DynamicParameters] [ParamName]
...@@ -478,10 +475,10 @@ public DynamicParameters Output<T>(T target, Expression<Func<T, object>> express ...@@ -478,10 +475,10 @@ public DynamicParameters Output<T>(T target, Expression<Func<T, object>> express
{ {
// Finally, prep the parameter and attach the callback to it // Finally, prep the parameter and attach the callback to it
ParamInfo parameter; ParamInfo parameter;
var targetMemberType = lastMemberAccess.Type; var targetMemberType = lastMemberAccess?.Type;
int sizeToSet = (!size.HasValue && targetMemberType == typeof(string)) ? DbString.DefaultLength : size ?? 0; int sizeToSet = (!size.HasValue && targetMemberType == typeof(string)) ? DbString.DefaultLength : size ?? 0;
if (this.parameters.TryGetValue(dynamicParamName, out parameter)) if (parameters.TryGetValue(dynamicParamName, out parameter))
{ {
parameter.ParameterDirection = parameter.AttachedParam.Direction = ParameterDirection.InputOutput; parameter.ParameterDirection = parameter.AttachedParam.Direction = ParameterDirection.InputOutput;
...@@ -493,14 +490,14 @@ public DynamicParameters Output<T>(T target, Expression<Func<T, object>> express ...@@ -493,14 +490,14 @@ public DynamicParameters Output<T>(T target, Expression<Func<T, object>> express
else else
{ {
SqlMapper.ITypeHandler handler; SqlMapper.ITypeHandler handler;
dbType = (!dbType.HasValue) ? SqlMapper.LookupDbType(targetMemberType, targetMemberType.Name, true, out handler) : dbType; dbType = (!dbType.HasValue) ? SqlMapper.LookupDbType(targetMemberType, targetMemberType?.Name, true, out handler) : dbType;
// CameFromTemplate property would not apply here because this new param // CameFromTemplate property would not apply here because this new param
// Still needs to be added to the command // Still needs to be added to the command
this.Add(dynamicParamName, expression.Compile().Invoke(target), null, ParameterDirection.InputOutput, sizeToSet); Add(dynamicParamName, expression.Compile().Invoke(target), null, ParameterDirection.InputOutput, sizeToSet);
} }
parameter = this.parameters[dynamicParamName]; parameter = parameters[dynamicParamName];
parameter.OutputCallback = setter; parameter.OutputCallback = setter;
parameter.OutputTarget = target; parameter.OutputTarget = target;
}); });
...@@ -518,7 +515,7 @@ void SqlMapper.IParameterCallbacks.OnCompleted() ...@@ -518,7 +515,7 @@ void SqlMapper.IParameterCallbacks.OnCompleted()
{ {
foreach (var param in (from p in parameters select p.Value)) foreach (var param in (from p in parameters select p.Value))
{ {
if (param.OutputCallback != null) param.OutputCallback(param.OutputTarget, this); param.OutputCallback?.Invoke(param.OutputTarget, this);
} }
} }
} }
......
...@@ -28,7 +28,7 @@ private static readonly FeatureSupport ...@@ -28,7 +28,7 @@ private static readonly FeatureSupport
/// </summary> /// </summary>
public static FeatureSupport Get(IDbConnection connection) public static FeatureSupport Get(IDbConnection connection)
{ {
string name = connection == null ? null : connection.GetType().Name; string name = connection?.GetType().Name;
if (string.Equals(name, "npgsqlconnection", StringComparison.OrdinalIgnoreCase)) return postgres; if (string.Equals(name, "npgsqlconnection", StringComparison.OrdinalIgnoreCase)) return postgres;
return @default; return @default;
} }
...@@ -39,7 +39,7 @@ private FeatureSupport(bool arrays) ...@@ -39,7 +39,7 @@ private FeatureSupport(bool arrays)
/// <summary> /// <summary>
/// True if the db supports array columns e.g. Postgresql /// True if the db supports array columns e.g. Postgresql
/// </summary> /// </summary>
public bool Arrays { get; private set; } public bool Arrays { get; }
} }
} }
...@@ -8,11 +8,6 @@ namespace Dapper ...@@ -8,11 +8,6 @@ namespace Dapper
/// </summary> /// </summary>
sealed class SimpleMemberMap : SqlMapper.IMemberMap sealed class SimpleMemberMap : SqlMapper.IMemberMap
{ {
private readonly string _columnName;
private readonly PropertyInfo _property;
private readonly FieldInfo _field;
private readonly ParameterInfo _parameter;
/// <summary> /// <summary>
/// Creates instance for simple property mapping /// Creates instance for simple property mapping
/// </summary> /// </summary>
...@@ -21,13 +16,13 @@ sealed class SimpleMemberMap : SqlMapper.IMemberMap ...@@ -21,13 +16,13 @@ sealed class SimpleMemberMap : SqlMapper.IMemberMap
public SimpleMemberMap(string columnName, PropertyInfo property) public SimpleMemberMap(string columnName, PropertyInfo property)
{ {
if (columnName == null) if (columnName == null)
throw new ArgumentNullException("columnName"); throw new ArgumentNullException(nameof(columnName));
if (property == null) if (property == null)
throw new ArgumentNullException("property"); throw new ArgumentNullException(nameof(property));
_columnName = columnName; ColumnName = columnName;
_property = property; Property = property;
} }
/// <summary> /// <summary>
...@@ -38,13 +33,13 @@ public SimpleMemberMap(string columnName, PropertyInfo property) ...@@ -38,13 +33,13 @@ public SimpleMemberMap(string columnName, PropertyInfo property)
public SimpleMemberMap(string columnName, FieldInfo field) public SimpleMemberMap(string columnName, FieldInfo field)
{ {
if (columnName == null) if (columnName == null)
throw new ArgumentNullException("columnName"); throw new ArgumentNullException(nameof(columnName));
if (field == null) if (field == null)
throw new ArgumentNullException("field"); throw new ArgumentNullException(nameof(field));
_columnName = columnName; ColumnName = columnName;
_field = field; Field = field;
} }
/// <summary> /// <summary>
...@@ -55,66 +50,39 @@ public SimpleMemberMap(string columnName, FieldInfo field) ...@@ -55,66 +50,39 @@ public SimpleMemberMap(string columnName, FieldInfo field)
public SimpleMemberMap(string columnName, ParameterInfo parameter) public SimpleMemberMap(string columnName, ParameterInfo parameter)
{ {
if (columnName == null) if (columnName == null)
throw new ArgumentNullException("columnName"); throw new ArgumentNullException(nameof(columnName));
if (parameter == null) if (parameter == null)
throw new ArgumentNullException("parameter"); throw new ArgumentNullException(nameof(parameter));
_columnName = columnName; ColumnName = columnName;
_parameter = parameter; Parameter = parameter;
} }
/// <summary> /// <summary>
/// DataReader column name /// DataReader column name
/// </summary> /// </summary>
public string ColumnName public string ColumnName { get; }
{
get { return _columnName; }
}
/// <summary> /// <summary>
/// Target member type /// Target member type
/// </summary> /// </summary>
public Type MemberType public Type MemberType => Field?.FieldType ?? Property?.PropertyType ?? Parameter?.ParameterType;
{
get
{
if (_field != null)
return _field.FieldType;
if (_property != null)
return _property.PropertyType;
if (_parameter != null)
return _parameter.ParameterType;
return null;
}
}
/// <summary> /// <summary>
/// Target property /// Target property
/// </summary> /// </summary>
public PropertyInfo Property public PropertyInfo Property { get; }
{
get { return _property; }
}
/// <summary> /// <summary>
/// Target field /// Target field
/// </summary> /// </summary>
public FieldInfo Field public FieldInfo Field { get; }
{
get { return _field; }
}
/// <summary> /// <summary>
/// Target constructor parameter /// Target constructor parameter
/// </summary> /// </summary>
public ParameterInfo Parameter public ParameterInfo Parameter { get; }
{
get { return _parameter; }
}
} }
} }
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#if !DNXCORE50 #if !DNXCORE50
namespace Dapper namespace Dapper
{ {
sealed class SqlDataRecordHandler : Dapper.SqlMapper.ITypeHandler sealed class SqlDataRecordHandler : SqlMapper.ITypeHandler
{ {
public object Parse(Type destinationType, object value) public object Parse(Type destinationType, object value)
{ {
......
...@@ -9,7 +9,7 @@ namespace Dapper ...@@ -9,7 +9,7 @@ namespace Dapper
/// <summary> /// <summary>
/// Used to pass a IEnumerable&lt;SqlDataRecord&gt; as a SqlDataRecordListTVPParameter /// Used to pass a IEnumerable&lt;SqlDataRecord&gt; as a SqlDataRecordListTVPParameter
/// </summary> /// </summary>
sealed class SqlDataRecordListTVPParameter : Dapper.SqlMapper.ICustomQueryParameter sealed class SqlDataRecordListTVPParameter : SqlMapper.ICustomQueryParameter
{ {
private readonly IEnumerable<Microsoft.SqlServer.Server.SqlDataRecord> data; private readonly IEnumerable<Microsoft.SqlServer.Server.SqlDataRecord> data;
private readonly string typeName; private readonly string typeName;
......
...@@ -60,7 +60,7 @@ public static Task<IEnumerable<T>> QueryAsync<T>(this IDbConnection cnn, string ...@@ -60,7 +60,7 @@ public static Task<IEnumerable<T>> QueryAsync<T>(this IDbConnection cnn, string
/// </summary> /// </summary>
public static Task<IEnumerable<object>> QueryAsync(this IDbConnection cnn, Type type, string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) public static Task<IEnumerable<object>> QueryAsync(this IDbConnection cnn, Type type, string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null)
{ {
if (type == null) throw new ArgumentNullException("type"); if (type == null) throw new ArgumentNullException(nameof(type));
return QueryAsync<object>(cnn, type, new CommandDefinition(sql, (object)param, transaction, commandTimeout, commandType, CommandFlags.Buffered, default(CancellationToken))); return QueryAsync<object>(cnn, type, new CommandDefinition(sql, (object)param, transaction, commandTimeout, commandType, CommandFlags.Buffered, default(CancellationToken)));
} }
...@@ -83,7 +83,7 @@ public static Task<IEnumerable<object>> QueryAsync(this IDbConnection cnn, Type ...@@ -83,7 +83,7 @@ public static Task<IEnumerable<object>> QueryAsync(this IDbConnection cnn, Type
private static async Task<IEnumerable<T>> QueryAsync<T>(this IDbConnection cnn, Type effectiveType, CommandDefinition command) private static async Task<IEnumerable<T>> QueryAsync<T>(this IDbConnection cnn, Type effectiveType, CommandDefinition command)
{ {
object param = command.Parameters; object param = command.Parameters;
var identity = new Identity(command.CommandText, command.CommandType, cnn, effectiveType, param == null ? null : param.GetType(), null); var identity = new Identity(command.CommandText, command.CommandType, cnn, effectiveType, param?.GetType(), null);
var info = GetCacheInfo(identity, param, command.AddToCache); var info = GetCacheInfo(identity, param, command.AddToCache);
bool wasClosed = cnn.State == ConnectionState.Closed; bool wasClosed = cnn.State == ConnectionState.Closed;
var cancel = command.CancellationToken; var cancel = command.CancellationToken;
...@@ -177,8 +177,8 @@ private struct AsyncExecState ...@@ -177,8 +177,8 @@ private struct AsyncExecState
public readonly Task<int> Task; public readonly Task<int> Task;
public AsyncExecState(DbCommand command, Task<int> task) public AsyncExecState(DbCommand command, Task<int> task)
{ {
this.Command = command; Command = command;
this.Task = task; Task = task;
} }
} }
private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandDefinition command, IEnumerable multiExec) private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandDefinition command, IEnumerable multiExec)
...@@ -276,7 +276,7 @@ private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandD ...@@ -276,7 +276,7 @@ private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandD
} }
private static async Task<int> ExecuteImplAsync(IDbConnection cnn, CommandDefinition command, object param) private static async Task<int> ExecuteImplAsync(IDbConnection cnn, CommandDefinition command, object param)
{ {
var identity = new Identity(command.CommandText, command.CommandType, cnn, null, param == null ? null : param.GetType(), null); var identity = new Identity(command.CommandText, command.CommandType, cnn, null, param?.GetType(), null);
var info = GetCacheInfo(identity, param, command.AddToCache); var info = GetCacheInfo(identity, param, command.AddToCache);
bool wasClosed = cnn.State == ConnectionState.Closed; bool wasClosed = cnn.State == ConnectionState.Closed;
using (var cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader)) using (var cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader))
...@@ -542,8 +542,7 @@ private static IEnumerable<T> ExecuteReaderSync<T>(IDataReader reader, Func<IDat ...@@ -542,8 +542,7 @@ private static IEnumerable<T> ExecuteReaderSync<T>(IDataReader reader, Func<IDat
yield return (T)func(reader); yield return (T)func(reader);
} }
while (reader.NextResult()) { } while (reader.NextResult()) { }
if (parameters is SqlMapper.IParameterCallbacks) (parameters as IParameterCallbacks)?.OnCompleted();
((SqlMapper.IParameterCallbacks)parameters).OnCompleted();
} }
} }
...@@ -598,7 +597,7 @@ public static async Task<GridReader> QueryMultipleAsync(this IDbConnection cnn, ...@@ -598,7 +597,7 @@ public static async Task<GridReader> QueryMultipleAsync(this IDbConnection cnn,
{ /* don't spoil the existing exception */ } { /* don't spoil the existing exception */ }
reader.Dispose(); reader.Dispose();
} }
if (cmd != null) cmd.Dispose(); cmd?.Dispose();
if (wasClosed) cnn.Close(); if (wasClosed) cnn.Close();
throw; throw;
} }
...@@ -666,7 +665,7 @@ private static async Task<IDataReader> ExecuteReaderImplAsync(IDbConnection cnn, ...@@ -666,7 +665,7 @@ private static async Task<IDataReader> ExecuteReaderImplAsync(IDbConnection cnn,
finally finally
{ {
if (wasClosed) cnn.Close(); if (wasClosed) cnn.Close();
if (cmd != null) cmd.Dispose(); cmd?.Dispose();
} }
} }
...@@ -743,7 +742,7 @@ private async static Task<T> ExecuteScalarImplAsync<T>(IDbConnection cnn, Comman ...@@ -743,7 +742,7 @@ private async static Task<T> ExecuteScalarImplAsync<T>(IDbConnection cnn, Comman
finally finally
{ {
if (wasClosed) cnn.Close(); if (wasClosed) cnn.Close();
if (cmd != null) cmd.Dispose(); cmd?.Dispose();
} }
return Parse<T>(result); return Parse<T>(result);
} }
......
...@@ -17,8 +17,8 @@ private sealed class DapperRow ...@@ -17,8 +17,8 @@ private sealed class DapperRow
public DapperRow(DapperTable table, object[] values) public DapperRow(DapperTable table, object[] values)
{ {
if (table == null) throw new ArgumentNullException("table"); if (table == null) throw new ArgumentNullException(nameof(table));
if (values == null) throw new ArgumentNullException("values"); if (values == null) throw new ArgumentNullException(nameof(values));
this.table = table; this.table = table;
this.values = values; this.values = values;
} }
...@@ -136,11 +136,7 @@ IEnumerator IEnumerable.GetEnumerator() ...@@ -136,11 +136,7 @@ IEnumerator IEnumerable.GetEnumerator()
return dic.Remove(item.Key); return dic.Remove(item.Key);
} }
bool ICollection<KeyValuePair<string, object>>.IsReadOnly bool ICollection<KeyValuePair<string, object>>.IsReadOnly => false;
{
get { return false; }
}
#endregion #endregion
#region Implementation of IDictionary<string,object> #region Implementation of IDictionary<string,object>
...@@ -177,7 +173,7 @@ public object SetValue(string key, object value) ...@@ -177,7 +173,7 @@ public object SetValue(string key, object value)
} }
private object SetValue(string key, object value, bool isAdd) private object SetValue(string key, object value, bool isAdd)
{ {
if (key == null) throw new ArgumentNullException("key"); if (key == null) throw new ArgumentNullException(nameof(key));
int index = table.IndexOfName(key); int index = table.IndexOfName(key);
if (index < 0) if (index < 0)
{ {
...@@ -186,7 +182,7 @@ private object SetValue(string key, object value, bool isAdd) ...@@ -186,7 +182,7 @@ private object SetValue(string key, object value, bool isAdd)
else if (isAdd && index < values.Length && !(values[index] is DeadValue)) else if (isAdd && index < values.Length && !(values[index] is DeadValue))
{ {
// then semantically, this value already exists // then semantically, this value already exists
throw new ArgumentException("An item with the same key has already been added", "key"); throw new ArgumentException("An item with the same key has already been added", nameof(key));
} }
int oldLength = values.Length; int oldLength = values.Length;
if (oldLength <= index) if (oldLength <= index)
......
...@@ -10,11 +10,11 @@ private sealed class DapperTable ...@@ -10,11 +10,11 @@ private sealed class DapperTable
string[] fieldNames; string[] fieldNames;
readonly Dictionary<string, int> fieldNameLookup; readonly Dictionary<string, int> fieldNameLookup;
internal string[] FieldNames { get { return fieldNames; } } internal string[] FieldNames => fieldNames;
public DapperTable(string[] fieldNames) public DapperTable(string[] fieldNames)
{ {
if (fieldNames == null) throw new ArgumentNullException("fieldNames"); if (fieldNames == null) throw new ArgumentNullException(nameof(fieldNames));
this.fieldNames = fieldNames; this.fieldNames = fieldNames;
fieldNameLookup = new Dictionary<string, int>(fieldNames.Length, StringComparer.Ordinal); fieldNameLookup = new Dictionary<string, int>(fieldNames.Length, StringComparer.Ordinal);
...@@ -33,7 +33,7 @@ internal int IndexOfName(string name) ...@@ -33,7 +33,7 @@ internal int IndexOfName(string name)
} }
internal int AddField(string name) internal int AddField(string name)
{ {
if (name == null) throw new ArgumentNullException("name"); if (name == null) throw new ArgumentNullException(nameof(name));
if (fieldNameLookup.ContainsKey(name)) throw new InvalidOperationException("Field already exists: " + name); if (fieldNameLookup.ContainsKey(name)) throw new InvalidOperationException("Field already exists: " + name);
int oldLen = fieldNames.Length; int oldLen = fieldNames.Length;
Array.Resize(ref fieldNames, oldLen + 1); // yes, this is sub-optimal, but this is not the expected common case Array.Resize(ref fieldNames, oldLen + 1); // yes, this is sub-optimal, but this is not the expected common case
...@@ -48,7 +48,7 @@ internal bool FieldExists(string key) ...@@ -48,7 +48,7 @@ internal bool FieldExists(string key)
return key != null && fieldNameLookup.ContainsKey(key); return key != null && fieldNameLookup.ContainsKey(key);
} }
public int FieldCount { get { return fieldNames.Length; } } public int FieldCount => fieldNames.Length;
} }
} }
......
...@@ -45,7 +45,7 @@ public Task<IEnumerable<dynamic>> ReadAsync(bool buffered = true) ...@@ -45,7 +45,7 @@ public Task<IEnumerable<dynamic>> ReadAsync(bool buffered = true)
/// </summary> /// </summary>
public Task<IEnumerable<object>> ReadAsync(Type type, bool buffered = true) public Task<IEnumerable<object>> ReadAsync(Type type, bool buffered = true)
{ {
if (type == null) throw new ArgumentNullException("type"); if (type == null) throw new ArgumentNullException(nameof(type));
return ReadAsyncImpl<object>(type, buffered); return ReadAsyncImpl<object>(type, buffered);
} }
/// <summary> /// <summary>
...@@ -62,7 +62,7 @@ private async Task NextResultAsync() ...@@ -62,7 +62,7 @@ private async Task NextResultAsync()
{ {
readCount++; readCount++;
gridIndex++; gridIndex++;
consumed = false; IsConsumed = false;
} }
else else
{ {
...@@ -70,7 +70,7 @@ private async Task NextResultAsync() ...@@ -70,7 +70,7 @@ private async Task NextResultAsync()
// need for "Cancel" etc // need for "Cancel" etc
reader.Dispose(); reader.Dispose();
reader = null; reader = null;
if (callbacks != null) callbacks.OnCompleted(); callbacks?.OnCompleted();
Dispose(); Dispose();
} }
} }
...@@ -78,7 +78,7 @@ private async Task NextResultAsync() ...@@ -78,7 +78,7 @@ private async Task NextResultAsync()
private Task<IEnumerable<T>> ReadAsyncImpl<T>(Type type, bool buffered) private Task<IEnumerable<T>> ReadAsyncImpl<T>(Type type, bool buffered)
{ {
if (reader == null) throw new ObjectDisposedException(GetType().FullName, "The reader has been disposed; this can happen after all data has been consumed"); if (reader == null) throw new ObjectDisposedException(GetType().FullName, "The reader has been disposed; this can happen after all data has been consumed");
if (consumed) throw new InvalidOperationException("Query results must be consumed in the correct order, and each result can only be consumed once"); if (IsConsumed) throw new InvalidOperationException("Query results must be consumed in the correct order, and each result can only be consumed once");
var typedIdentity = identity.ForGrid(type, gridIndex); var typedIdentity = identity.ForGrid(type, gridIndex);
CacheInfo cache = GetCacheInfo(typedIdentity, null, addToCache); CacheInfo cache = GetCacheInfo(typedIdentity, null, addToCache);
var deserializer = cache.Deserializer; var deserializer = cache.Deserializer;
...@@ -89,8 +89,8 @@ private Task<IEnumerable<T>> ReadAsyncImpl<T>(Type type, bool buffered) ...@@ -89,8 +89,8 @@ private Task<IEnumerable<T>> ReadAsyncImpl<T>(Type type, bool buffered)
deserializer = new DeserializerState(hash, GetDeserializer(type, reader, 0, -1, false)); deserializer = new DeserializerState(hash, GetDeserializer(type, reader, 0, -1, false));
cache.Deserializer = deserializer; cache.Deserializer = deserializer;
} }
consumed = true; IsConsumed = true;
if (buffered && this.reader is DbDataReader) if (buffered && reader is DbDataReader)
{ {
return ReadBufferedAsync<T>(gridIndex, deserializer.Func, typedIdentity); return ReadBufferedAsync<T>(gridIndex, deserializer.Func, typedIdentity);
} }
...@@ -104,27 +104,23 @@ private Task<IEnumerable<T>> ReadAsyncImpl<T>(Type type, bool buffered) ...@@ -104,27 +104,23 @@ private Task<IEnumerable<T>> ReadAsyncImpl<T>(Type type, bool buffered)
private async Task<IEnumerable<T>> ReadBufferedAsync<T>(int index, Func<IDataReader, object> deserializer, Identity typedIdentity) private async Task<IEnumerable<T>> ReadBufferedAsync<T>(int index, Func<IDataReader, object> deserializer, Identity typedIdentity)
{ {
//try try
//{ {
var reader = (DbDataReader)this.reader; var reader = (DbDataReader)this.reader;
List<T> buffer = new List<T>(); List<T> buffer = new List<T>();
while (index == gridIndex && await reader.ReadAsync(cancel).ConfigureAwait(false)) while (index == gridIndex && await reader.ReadAsync(cancel).ConfigureAwait(false))
{ {
buffer.Add((T)deserializer(reader)); buffer.Add((T)deserializer(reader));
} }
if (index == gridIndex) // need to do this outside of the finally pre-C#6 return buffer;
}
finally // finally so that First etc progresses things even when multiple rows
{
if (index == gridIndex)
{ {
await NextResultAsync().ConfigureAwait(false); await NextResultAsync().ConfigureAwait(false);
} }
return buffer; }
//}
//finally // finally so that First etc progresses things even when multiple rows
//{
// if (index == gridIndex)
// {
// await NextResultAsync().ConfigureAwait(false);
// }
//}
} }
} }
......
...@@ -27,13 +27,12 @@ partial class SqlMapper ...@@ -27,13 +27,12 @@ partial class SqlMapper
public partial class GridReader : IDisposable public partial class GridReader : IDisposable
{ {
private IDataReader reader; private IDataReader reader;
private IDbCommand command;
private Identity identity; private Identity identity;
private bool addToCache; private bool addToCache;
internal GridReader(IDbCommand command, IDataReader reader, Identity identity, SqlMapper.IParameterCallbacks callbacks, bool addToCache) internal GridReader(IDbCommand command, IDataReader reader, Identity identity, IParameterCallbacks callbacks, bool addToCache)
{ {
this.Command = command; Command = command;
this.reader = reader; this.reader = reader;
this.identity = identity; this.identity = identity;
this.callbacks = callbacks; this.callbacks = callbacks;
...@@ -62,14 +61,14 @@ public IEnumerable<T> Read<T>(bool buffered = true) ...@@ -62,14 +61,14 @@ public IEnumerable<T> Read<T>(bool buffered = true)
/// </summary> /// </summary>
public IEnumerable<object> Read(Type type, bool buffered = true) public IEnumerable<object> Read(Type type, bool buffered = true)
{ {
if (type == null) throw new ArgumentNullException("type"); if (type == null) throw new ArgumentNullException(nameof(type));
return ReadImpl<object>(type, buffered); return ReadImpl<object>(type, buffered);
} }
private IEnumerable<T> ReadImpl<T>(Type type, bool buffered) private IEnumerable<T> ReadImpl<T>(Type type, bool buffered)
{ {
if (reader == null) throw new ObjectDisposedException(GetType().FullName, "The reader has been disposed; this can happen after all data has been consumed"); if (reader == null) throw new ObjectDisposedException(GetType().FullName, "The reader has been disposed; this can happen after all data has been consumed");
if (consumed) throw new InvalidOperationException("Query results must be consumed in the correct order, and each result can only be consumed once"); if (IsConsumed) throw new InvalidOperationException("Query results must be consumed in the correct order, and each result can only be consumed once");
var typedIdentity = identity.ForGrid(type, gridIndex); var typedIdentity = identity.ForGrid(type, gridIndex);
CacheInfo cache = GetCacheInfo(typedIdentity, null, addToCache); CacheInfo cache = GetCacheInfo(typedIdentity, null, addToCache);
var deserializer = cache.Deserializer; var deserializer = cache.Deserializer;
...@@ -80,7 +79,7 @@ private IEnumerable<T> ReadImpl<T>(Type type, bool buffered) ...@@ -80,7 +79,7 @@ private IEnumerable<T> ReadImpl<T>(Type type, bool buffered)
deserializer = new DeserializerState(hash, GetDeserializer(type, reader, 0, -1, false)); deserializer = new DeserializerState(hash, GetDeserializer(type, reader, 0, -1, false));
cache.Deserializer = deserializer; cache.Deserializer = deserializer;
} }
consumed = true; IsConsumed = true;
var result = ReadDeferred<T>(gridIndex, deserializer.Func, typedIdentity); var result = ReadDeferred<T>(gridIndex, deserializer.Func, typedIdentity);
return buffered ? result.ToList() : result; return buffered ? result.ToList() : result;
} }
...@@ -99,7 +98,7 @@ private IEnumerable<T> ReadImpl<T>(Type type, bool buffered) ...@@ -99,7 +98,7 @@ private IEnumerable<T> ReadImpl<T>(Type type, bool buffered)
}, gridIndex); }, gridIndex);
try try
{ {
foreach (var r in SqlMapper.MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(null, default(CommandDefinition), func, splitOn, reader, identity, false)) foreach (var r in MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(null, default(CommandDefinition), func, splitOn, reader, identity, false))
{ {
yield return r; yield return r;
} }
...@@ -115,7 +114,7 @@ private IEnumerable<TReturn> MultiReadInternal<TReturn>(Type[] types, Func<objec ...@@ -115,7 +114,7 @@ private IEnumerable<TReturn> MultiReadInternal<TReturn>(Type[] types, Func<objec
var identity = this.identity.ForGrid(typeof(TReturn), types, gridIndex); var identity = this.identity.ForGrid(typeof(TReturn), types, gridIndex);
try try
{ {
foreach (var r in SqlMapper.MultiMapImpl<TReturn>(null, default(CommandDefinition), types, map, splitOn, reader, identity, false)) foreach (var r in MultiMapImpl<TReturn>(null, default(CommandDefinition), types, map, splitOn, reader, identity, false))
{ {
yield return r; yield return r;
} }
...@@ -205,34 +204,17 @@ private IEnumerable<T> ReadDeferred<T>(int index, Func<IDataReader, object> dese ...@@ -205,34 +204,17 @@ private IEnumerable<T> ReadDeferred<T>(int index, Func<IDataReader, object> dese
} }
} }
private int gridIndex, readCount; private int gridIndex, readCount;
private bool consumed; private IParameterCallbacks callbacks;
private SqlMapper.IParameterCallbacks callbacks;
/// <summary> /// <summary>
/// Has the underlying reader been consumed? /// Has the underlying reader been consumed?
/// </summary> /// </summary>
public bool IsConsumed public bool IsConsumed { get; private set; }
{
get
{
return consumed;
}
}
/// <summary> /// <summary>
/// The command associated with the reader /// The command associated with the reader
/// </summary> /// </summary>
public IDbCommand Command public IDbCommand Command { get; set; }
{
get
{
return command;
}
set
{
command = value;
}
}
private void NextResult() private void NextResult()
{ {
...@@ -240,7 +222,7 @@ private void NextResult() ...@@ -240,7 +222,7 @@ private void NextResult()
{ {
readCount++; readCount++;
gridIndex++; gridIndex++;
consumed = false; IsConsumed = false;
} }
else else
{ {
...@@ -248,7 +230,7 @@ private void NextResult() ...@@ -248,7 +230,7 @@ private void NextResult()
// need for "Cancel" etc // need for "Cancel" etc
reader.Dispose(); reader.Dispose();
reader = null; reader = null;
if (callbacks != null) callbacks.OnCompleted(); callbacks?.OnCompleted();
Dispose(); Dispose();
} }
} }
...@@ -259,7 +241,7 @@ public void Dispose() ...@@ -259,7 +241,7 @@ public void Dispose()
{ {
if (reader != null) if (reader != null)
{ {
if (!reader.IsClosed && Command != null) Command.Cancel(); if (!reader.IsClosed) Command?.Cancel();
reader.Dispose(); reader.Dispose();
reader = null; reader = null;
} }
......
...@@ -58,17 +58,17 @@ private Identity(string sql, CommandType? commandType, string connectionString, ...@@ -58,17 +58,17 @@ private Identity(string sql, CommandType? commandType, string connectionString,
hashCode = 17; // we *know* we are using this in a dictionary, so pre-compute this hashCode = 17; // we *know* we are using this in a dictionary, so pre-compute this
hashCode = hashCode * 23 + commandType.GetHashCode(); hashCode = hashCode * 23 + commandType.GetHashCode();
hashCode = hashCode * 23 + gridIndex.GetHashCode(); hashCode = hashCode * 23 + gridIndex.GetHashCode();
hashCode = hashCode * 23 + (sql == null ? 0 : sql.GetHashCode()); hashCode = hashCode * 23 + (sql?.GetHashCode() ?? 0);
hashCode = hashCode * 23 + (type == null ? 0 : type.GetHashCode()); hashCode = hashCode * 23 + (type?.GetHashCode() ?? 0);
if (otherTypes != null) if (otherTypes != null)
{ {
foreach (var t in otherTypes) foreach (var t in otherTypes)
{ {
hashCode = hashCode * 23 + (t == null ? 0 : t.GetHashCode()); hashCode = hashCode * 23 + (t?.GetHashCode() ?? 0);
} }
} }
hashCode = hashCode * 23 + (connectionString == null ? 0 : SqlMapper.connectionStringComparer.GetHashCode(connectionString)); hashCode = hashCode * 23 + (connectionString == null ? 0 : connectionStringComparer.GetHashCode(connectionString));
hashCode = hashCode * 23 + (parametersType == null ? 0 : parametersType.GetHashCode()); hashCode = hashCode * 23 + (parametersType?.GetHashCode() ?? 0);
} }
} }
...@@ -127,7 +127,7 @@ public bool Equals(Identity other) ...@@ -127,7 +127,7 @@ public bool Equals(Identity other)
type == other.type && type == other.type &&
sql == other.sql && sql == other.sql &&
commandType == other.commandType && commandType == other.commandType &&
SqlMapper.connectionStringComparer.Equals(connectionString, other.connectionString) && connectionStringComparer.Equals(connectionString, other.connectionString) &&
parametersType == other.parametersType; parametersType == other.parametersType;
} }
} }
......
...@@ -49,9 +49,9 @@ private Link(TKey key, TValue value, Link<TKey, TValue> tail) ...@@ -49,9 +49,9 @@ private Link(TKey key, TValue value, Link<TKey, TValue> tail)
Value = value; Value = value;
Tail = tail; Tail = tail;
} }
public TKey Key { get; private set; } public TKey Key { get; }
public TValue Value { get; private set; } public TValue Value { get; }
public Link<TKey, TValue> Tail { get; private set; } public Link<TKey, TValue> Tail { get; }
} }
} }
} }
...@@ -9,20 +9,20 @@ partial class SqlMapper ...@@ -9,20 +9,20 @@ partial class SqlMapper
/// </summary> /// </summary>
internal struct LiteralToken internal struct LiteralToken
{ {
private readonly string token, member;
/// <summary> /// <summary>
/// The text in the original command that should be replaced /// The text in the original command that should be replaced
/// </summary> /// </summary>
public string Token { get { return token; } } public string Token { get; }
/// <summary> /// <summary>
/// The name of the member referred to by the token /// The name of the member referred to by the token
/// </summary> /// </summary>
public string Member { get { return member; } } public string Member { get; }
internal LiteralToken(string token, string member) internal LiteralToken(string token, string member)
{ {
this.token = token; Token = token;
this.member = member; Member = member;
} }
internal static readonly IList<LiteralToken> None = new LiteralToken[0]; internal static readonly IList<LiteralToken> None = new LiteralToken[0];
......
This diff is collapsed.
...@@ -8,7 +8,7 @@ namespace Dapper ...@@ -8,7 +8,7 @@ namespace Dapper
/// <summary> /// <summary>
/// Used to pass a DataTable as a TableValuedParameter /// Used to pass a DataTable as a TableValuedParameter
/// </summary> /// </summary>
sealed class TableValuedParameter : Dapper.SqlMapper.ICustomQueryParameter sealed class TableValuedParameter : SqlMapper.ICustomQueryParameter
{ {
private readonly DataTable table; private readonly DataTable table;
private readonly string typeName; private readonly string typeName;
...@@ -47,14 +47,14 @@ internal static void Set(IDbDataParameter parameter, DataTable table, string typ ...@@ -47,14 +47,14 @@ internal static void Set(IDbDataParameter parameter, DataTable table, string typ
parameter.Value = SqlMapper.SanitizeParameterValue(table); parameter.Value = SqlMapper.SanitizeParameterValue(table);
if (string.IsNullOrEmpty(typeName) && table != null) if (string.IsNullOrEmpty(typeName) && table != null)
{ {
typeName = SqlMapper.GetTypeName(table); typeName = table.GetTypeName();
} }
if (!string.IsNullOrEmpty(typeName)) if (!string.IsNullOrEmpty(typeName))
{ {
var sqlParam = parameter as System.Data.SqlClient.SqlParameter; var sqlParam = parameter as System.Data.SqlClient.SqlParameter;
if (sqlParam != null) if (sqlParam != null)
{ {
if (setTypeName != null) setTypeName(sqlParam, typeName); setTypeName?.Invoke(sqlParam, typeName);
sqlParam.SqlDbType = SqlDbType.Structured; sqlParam.SqlDbType = SqlDbType.Structured;
} }
} }
......
...@@ -252,23 +252,17 @@ public WrappedReader(IDbCommand cmd, IDataReader reader) ...@@ -252,23 +252,17 @@ public WrappedReader(IDbCommand cmd, IDataReader reader)
void IDataReader.Close() void IDataReader.Close()
{ {
if (reader != null) reader.Close(); reader?.Close();
} }
int IDataReader.Depth int IDataReader.Depth => Reader.Depth;
{
get { return Reader.Depth; }
}
DataTable IDataReader.GetSchemaTable() DataTable IDataReader.GetSchemaTable()
{ {
return Reader.GetSchemaTable(); return Reader.GetSchemaTable();
} }
bool IDataReader.IsClosed bool IDataReader.IsClosed => reader?.IsClosed ?? true;
{
get { return reader == null ? true : reader.IsClosed; }
}
bool IDataReader.NextResult() bool IDataReader.NextResult()
{ {
...@@ -280,24 +274,18 @@ bool IDataReader.Read() ...@@ -280,24 +274,18 @@ bool IDataReader.Read()
return Reader.Read(); return Reader.Read();
} }
int IDataReader.RecordsAffected int IDataReader.RecordsAffected => Reader.RecordsAffected;
{
get { return Reader.RecordsAffected; }
}
void IDisposable.Dispose() void IDisposable.Dispose()
{ {
if (reader != null) reader.Close(); reader?.Close();
if (reader != null) reader.Dispose(); reader?.Dispose();
reader = null; reader = null;
if (cmd != null) cmd.Dispose(); cmd?.Dispose();
cmd = null; cmd = null;
} }
int IDataRecord.FieldCount int IDataRecord.FieldCount => Reader.FieldCount;
{
get { return Reader.FieldCount; }
}
bool IDataRecord.GetBoolean(int i) bool IDataRecord.GetBoolean(int i)
{ {
...@@ -409,15 +397,9 @@ bool IDataRecord.IsDBNull(int i) ...@@ -409,15 +397,9 @@ bool IDataRecord.IsDBNull(int i)
return Reader.IsDBNull(i); return Reader.IsDBNull(i);
} }
object IDataRecord.this[string name] object IDataRecord.this[string name] => Reader[name];
{
get { return Reader[name]; }
}
object IDataRecord.this[int i] object IDataRecord.this[int i] => Reader[i];
{
get { return Reader[i]; }
}
} }
#endif #endif
} }
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