/// <summary> /// Generate a complete list before returning. /// </summary> /// <typeparam name="TEntity">Type of entity to map</typeparam> /// <param name="cmd">Command to invoke <c>ExecuteReaderAsync()</c> on.</param> /// <param name="mapper">Mapper to use when converting rows to entities</param> /// <returns>A list which is generated asynchronously.</returns> /// <remarks> /// <para> /// Make sure that you <c>await</c> the method, as nothing the reader is not disposed directly if you don't. /// </para> /// </remarks> public static async Task <IList <TEntity> > ToListAsync <TEntity>(this IDbCommand cmd, IEntityMapper <TEntity> mapper) { if (cmd == null) { throw new ArgumentNullException("cmd"); } if (mapper == null) { throw new ArgumentNullException("mapper"); } var items = new List <TEntity>(); var command = GetDbCommandFromInterface(cmd); try { using (var reader = await command.ExecuteReaderAsync()) { while (await reader.ReadAsync()) { var entity = mapper.Create(reader); mapper.Map(reader, entity); items.Add((TEntity)entity); } } return(items); } catch (Exception e) { throw cmd.CreateDataException(e); } }
/// <summary> /// Generate a complete list before returning. /// </summary> /// <typeparam name="TEntity">Type of entity to use, must have an mapper registered in <see cref="EntityMappingProvider"/>.</typeparam> /// <param name="cmd">Command to invoke <c>ExecuteReader()</c> on.</param> /// <param name="mapper">Mapper to use when converting the rows to entities</param> /// <returns>A collection of entities, or an empty collection if no entities are found.</returns> /// <example> /// <code> /// <![CDATA[ /// public void FindByName(string firstName, string lastName) /// { /// using (var command = connection.CreateCommand()) /// { /// cmd.CommandText = "SELECT * FROM Users WHERE "; /// if (lastName != null) /// { /// cmd.AddParameter("firstName", firstName + "%"); /// cmd.CommandText += "FirstName LIKE @firstName AND "; /// } /// if (lastName != null) /// { /// cmd.AddParameter("lastName", lastName + "%"); /// cmd.CommandText += "LastName LIKE @lastName AND "; /// } /// /// cmd.CommandText = cmd.CommandText.Remove(cmd.CommandText.Length - 4, 4); /// return cmd.ToList<User>(); /// } /// } /// ]]> /// </code> /// </example> public static IList <TEntity> ToList <TEntity>(this IDbCommand cmd, ICrudEntityMapper <TEntity> mapper) { if (cmd == null) { throw new ArgumentNullException("cmd"); } if (mapper == null) { throw new ArgumentNullException("mapper"); } try { var items = new List <TEntity>(10); using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { var entity = mapper.Create(reader); mapper.Map(reader, entity); items.Add((TEntity)entity); } } return(items); } catch (Exception e) { throw cmd.CreateDataException(e); } }
/// <summary> /// Fetches the first row and maps it as an entity (if found). /// </summary> /// <typeparam name="TEntity">Type of entity to use, must have an mapper registered in <see cref="EntityMappingProvider"/>.</typeparam> /// <param name="cmd">Command to invoke <c>ExecuteReader()</c> on.</param> /// <param name="mapper">Mapper which can convert the db row to an entity.</param> /// <returns>Entity if found; otherwise <c>null</c>.</returns> /// <example> /// <code> /// <![CDATA[ /// public void FindUser(string id) /// { /// using (var command = connection.CreateCommand()) /// { /// cmd.CommandText = "SELECT * FROM Users WHERE Id = @id"; /// cmd.AddParameter("id", userId); /// return cmd.FirstOrDefault<User>(new MyCustomUserMapper()); /// } /// } /// ]]> /// </code> /// </example> public static TEntity FirstOrDefault <TEntity>(this IDbCommand cmd, ICrudEntityMapper <TEntity> mapper) { if (cmd == null) { throw new ArgumentNullException("cmd"); } if (mapper == null) { throw new ArgumentNullException("mapper"); } try { using (var reader = cmd.ExecuteReader()) { if (!reader.Read()) { return(default(TEntity)); } var entity = mapper.Create(reader); mapper.Map(reader, entity); return((TEntity)entity); } } catch (Exception e) { throw cmd.CreateDataException(e); } }
/// <summary> /// Fetches the first row and maps it as an entity (if found). /// </summary> /// <typeparam name="TEntity">Type of entity to use, must have an mapper registered in <see cref="EntityMappingProvider"/>.</typeparam> /// <param name="cmd">Command to invoke <c>ExecuteReader()</c> on.</param> /// <returns>Entity if found; otherwise <c>null</c>.</returns> /// <example> /// <code> /// <![CDATA[ /// public void FindUser(string id) /// { /// using (var command = connection.CreateCommand()) /// { /// cmd.CommandText = "SELECT * FROM Users WHERE Id = @id"; /// cmd.AddParameter("id", userId); /// return cmd.FirstOrDefault<User>(); /// } /// } /// ]]> /// </code> /// </example> public static TEntity FirstOrDefault <TEntity>(this IDbCommand cmd) { if (cmd == null) { throw new ArgumentNullException("cmd"); } try { using (var reader = cmd.ExecuteReader()) { if (!reader.Read()) { return(default(TEntity)); } var mapping = EntityMappingProvider.GetMapper <TEntity>(); var entity = (TEntity)mapping.Create(reader); mapping.Map(reader, entity); return(entity); } } catch (Exception e) { throw cmd.CreateDataException(e); } }
/// <summary> /// Return an enumerable which uses lazy loading of each row. /// </summary> /// <typeparam name="TEntity">Type of entity to use, must have an mapper registered in <see cref="EntityMappingProvider"/>.</typeparam> /// <param name="cmd">Command to invoke <c>ExecuteReader()</c> on.</param> /// <param name="ownsConnection"> /// <c>true</c> if the connection should be disposed together with the command/datareader. See /// remarks. /// </param> /// <param name="mapper">Mapper which convert a db row to an entity</param> /// <returns>Lazy loaded enumerator</returns> /// <remarks> /// <para> /// The returned enumerator will not map each row until it's requested. To be able to do that the /// connection/command/datareader is /// kept open until the enumerator is disposed. Hence it's important that you make sure that the enumerator is /// disposed when you are /// done with it. /// </para> /// <para> /// As the returned item is a custom lazy loaded enumerable it's quite fast as nothing is mapped if you do like: /// </para> /// <example> /// <code> /// <![CDATA[ /// using (var cmd = connection.CreateCommand()) /// { /// cmd.CommandText = "SELECT * FROM Users"; /// var pagedUsers = cmd.ToEnumerable<User>().Skip(1000).Take(50).ToList(); /// } /// ]]> /// </code> /// </example> /// <para> /// Do note that it will still read all rows and is therefore slower than paging in the SQL server. It will however /// use a lot less /// allocations than building a complete list first. /// </para> /// <para> /// If the result returnd from the query is all records that you want it's probably more effecient to use /// <see cref="ToList{TEntity}(IDbCommand)" />. /// </para> /// </remarks> /// <example> /// <code> /// <![CDATA[ /// public TimeSpan CalculateWorkHours() /// { /// int minutes = 0; /// using (var command = connection.CreateCommand()) /// { /// cmd.CommandText = "SELECT * FROM Users WHERE Id = @id"; /// cmd.AddParameter("id", userId); /// /// // can contain a large amount of rows without consuming memory /// using (var incidents = cmd.ToEnumerable<Incident>()) /// { /// foreach (var incident in incidents) /// { /// if (!incident.IsStarted) /// continue; /// /// var spentTime = incident.ReportedTime.Sum(x => x.TotalSpentTime); /// minutes += spentTime; /// } /// } /// } /// /// return TimeSpan.FromMinutes(minutes); /// } /// ]]> /// </code> /// </example> public static IEnumerable <TEntity> ToEnumerable <TEntity>(this IDbCommand cmd, bool ownsConnection, ICrudEntityMapper <TEntity> mapper) { if (cmd == null) { throw new ArgumentNullException("cmd"); } if (mapper == null) { throw new ArgumentNullException("mapper"); } try { var reader = cmd.ExecuteReader(); return(new AdoNetEntityEnumerable <TEntity>(cmd, reader, mapper, ownsConnection)); } catch (Exception e) { throw cmd.CreateDataException(e); } }
public static void ExecuteNonQuery(this IDbCommand cmd, string sql, object parameters = null) { if (cmd == null) { throw new ArgumentNullException(","); } try { cmd.CommandText = sql; if (parameters != null) { foreach (var kvp in parameters.ToDictionary()) { cmd.AddParameter(kvp.Key, kvp.Value ?? DBNull.Value); } } cmd.ExecuteNonQuery(); } catch (Exception e) { throw cmd.CreateDataException(e); } }