/// <summary> /// Set up a table-valued parameter to a procedure. /// </summary> /// <param name="command">The command to operate on.</param> /// <param name="parameter">The parameter to set up.</param> /// <param name="list">The list of records.</param> /// <param name="listType">The type of object in the list.</param> public override void SetupTableValuedParameter(IDbCommand command, IDataParameter parameter, System.Collections.IEnumerable list, Type listType) { if (command == null) { throw new ArgumentNullException("command"); } if (list == null) { throw new ArgumentNullException("list"); } var isEmpty = !list.GetEnumerator().MoveNext(); // if the list is empty, then we can optimize by omitting the table if (isEmpty && command.CommandType == CommandType.StoredProcedure) { parameter.Value = null; return; } // see if we already have a reader for the given type and table type name // we can't use the schema cache because we don't have a schema yet var key = Tuple.Create <string, string, string, Type>(command.Connection.ConnectionString, command.CommandText, parameter.ParameterName, listType); // infer the name of the structured table type for the parameter SqlParameter sqlParameter = (SqlParameter)parameter; sqlParameter.SqlDbType = SqlDbType.Structured; sqlParameter.TypeName = _tvpTypeNames.GetOrAdd( key, k => GetTableParameterTypeName(command, parameter, listType) ); ObjectReader objectReader = (ObjectReader)_tvpReaders.GetOrAdd( key, k => command.Connection.ExecuteAndAutoClose( _ => null, (_, __) => { using (var reader = GetTableTypeSchema(command, parameter)) return(ObjectReader.GetObjectReader(command, reader, listType)); }, CommandBehavior.Default)); if (!isEmpty) { parameter.Value = new SqlDataRecordAdapter(objectReader, list); } }
/// <summary> /// Set up a table-valued parameter to a procedure. /// </summary> /// <param name="command">The command to operate on.</param> /// <param name="parameter">The parameter to set up.</param> /// <param name="list">The list of records.</param> /// <param name="listType">The type of object in the list.</param> public override void SetupTableValuedParameter(IDbCommand command, IDataParameter parameter, System.Collections.IEnumerable list, Type listType) { if (command == null) { throw new ArgumentNullException("command"); } if (list == null) { throw new ArgumentNullException("list"); } // if the list is empty, then we can optimize by omitting the table if (command.CommandType == CommandType.StoredProcedure && !list.GetEnumerator().MoveNext()) { parameter.Value = null; return; } // allow the provider to make sure the table parameter is set up properly string tableTypeName = GetTableParameterTypeName(parameter, listType); // see if we already have a reader for the given type and table type name // we can't use the schema cache because we don't have a schema yet var key = Tuple.Create <string, string, Type>(command.Connection.ConnectionString, tableTypeName, listType); ObjectReader objectReader = (ObjectReader)_tvpReaders.GetOrAdd( key, k => command.Connection.ExecuteAndAutoClose( _ => null, (_, __) => { using (var reader = GetTableTypeSchema(command, parameter)) return(ObjectReader.GetObjectReader(command, reader, listType)); }, CommandBehavior.Default)); // create the structured parameter parameter.Value = new ObjectListDbDataReader(objectReader, list); }