/// <summary> /// Return an enumerable which uses lazy loading of each row. /// </summary> /// <typeparam name="TEntity">Type of entity to map</typeparam> /// <param name="unitOfWork">UnitOfWork to invoke <c>ExecuteReaderAsync()</c> on (through a created <c>DbCommand</c>).</param> /// <param name="ownsConnection"> /// <c>true</c> if the connection should be disposed together with the command/datareader. See /// remarks. /// </param> /// <param name="query">Query or short query (<c><![CDATA["projectId = @id AND dateCreated < @minDate"]]></c>)</param> /// <param name="parameters">Anonymous object (<c>new { id = dto.ProjectId, @minDate = dto.MinDate }</c>), a dictionary or a value array</param> /// <returns>Lazy loaded enumerator</returns> /// <remarks> /// <para> /// For more information about the "query" and "parameters" arguments, see <see cref="CommandExtensions.ApplyQuerySql{TEntity}"/>. /// </para> /// <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>Uses <see cref="EntityMappingProvider" /> to find the correct <c><![CDATA[IEntityMapper<TEntity>]]></c>.</para> /// </remarks> /// <example> /// <code> /// // All these examples are valid: /// <![CDATA[ /// var users = await unitOfWork.ToEnumerable<User>(true, "Age < 10"); /// var users = await unitOfWork.ToEnumerable<User>(true, "SELECT * FROM Users WHERE Age = 37"); /// var users = await unitOfWork.ToEnumerable<User>(true, "FirstName = @name", new { name = user.FirstName }); /// var users = await unitOfWork.ToEnumerable<User>(true, "FirstName = @1 AND Age < @2", 'A%', 35); /// var users = await unitOfWork.ToEnumerable<User>(true, "SELECT * FROM Users WHERE Age = @age LIMIT 1, 10", new { age = submittedAge }); /// var users = await unitOfWork.ToEnumerable<User>(true, "SELECT * FROM Users WHERE Age = @1 LIMIT 1, 10", user.FirstName); /// ]]> /// </code> /// </example> public static async Task <IEnumerable <TEntity> > ToEnumerableAsync <TEntity>(this IAdoNetUnitOfWork unitOfWork, bool ownsConnection, string query, params object[] parameters) { if (unitOfWork == null) { throw new ArgumentNullException("unitOfWork"); } if (query == null) { throw new ArgumentNullException("query"); } if (parameters == null) { throw new ArgumentNullException("parameters"); } var mapping = EntityMappingProvider.GetMapper <TEntity>(); //no using since AdoNetEntityEnumerable will own it. var cmd = unitOfWork.CreateDbCommand(); try { cmd.ApplyQuerySql(mapping, query, parameters); var reader = await cmd.ExecuteReaderAsync(); return(new AdoNetEntityEnumerable <TEntity>(cmd, reader, mapping, ownsConnection)); } catch (Exception e) { throw cmd.CreateDataException(e); } }
/// <summary> /// Insert a new row into the database. /// </summary> /// <typeparam name="TEntity"> /// Type of entity to use, must have an mapper registered in <see cref="EntityMappingProvider" /> /// . /// </typeparam> /// <param name="unitOfWork">Unit of work to execute command in.</param> /// <param name="entity">entity to insert into the database.</param> /// <returns>Task to wait on for completion</returns> /// <remarks> /// <para> /// Will assign the PK value to the /// </para> /// </remarks> /// <example> /// <code> /// var user = new User(10, "Jonas"); /// using (var uow = UnitOfWorkFactory.Create()) /// { /// await uow.InsertAsync(user); /// } /// </code> /// </example> public static async Task <object> InsertAsync <TEntity>(this IAdoNetUnitOfWork unitOfWork, TEntity entity) { if (unitOfWork == null) { throw new ArgumentNullException("unitOfWork"); } if (EqualityComparer <TEntity> .Default.Equals(default(TEntity), entity)) { throw new ArgumentNullException("entity"); } var mapper = EntityMappingProvider.GetMapper <TEntity>(); using (var cmd = (DbCommand)unitOfWork.CreateCommand()) { try { mapper.CommandBuilder.InsertCommand(cmd, entity); var value = await cmd.AssignAutoIncrementIfConfigured(entity, mapper); return(value ?? await cmd.ExecuteScalarAsync()); } catch (Exception e) { throw cmd.CreateDataException(e); } } }
/// <summary> /// Insert a new row into the database. /// </summary> /// <typeparam name="TEntity"> /// Type of entity to use, must have an mapper registered in <see cref="EntityMappingProvider" /> /// . /// </typeparam> /// <param name="unitOfWork">Unit of work to execute command in.</param> /// <param name="entity">entity to insert into the database.</param> /// <returns>Task to wait on for completion</returns> /// <remarks> /// <para> /// Will assign the PK value to the /// </para> /// </remarks> /// <example> /// <code> /// var user = new User(10, "Jonas"); /// using (var uow = UnitOfWorkFactory.Create()) /// { /// await uow.InsertAsync(user); /// } /// </code> /// </example> public static async Task <object> InsertAsync <TEntity>(this IAdoNetUnitOfWork unitOfWork, TEntity entity) { if (unitOfWork == null) { throw new ArgumentNullException("unitOfWork"); } if (EqualityComparer <TEntity> .Default.Equals(default(TEntity), entity)) { throw new ArgumentNullException("entity"); } var mapper = EntityMappingProvider.GetMapper <TEntity>(); using (var cmd = (DbCommand)unitOfWork.CreateCommand()) { mapper.CommandBuilder.InsertCommand(cmd, entity); //var keys = mapper.GetKeys(entity); //if (keys.Length == 1 && true) //{ // var id = await cmd.ExecuteScalarAsync(); // mapper.Properties[keys[0].Key].SetColumnValue(entity, id); //} return(await cmd.ExecuteScalarAsync()); } }
/// <summary> /// Truncate a table (remove all rows) /// </summary> /// <typeparam name="TEntity">Type of entity to use, must have an mapper registered in <see cref="EntityMappingProvider"/>.</typeparam> /// <param name="connection">Connection to create and execute our command on</param> public static void Truncate <TEntity>(this IDbConnection connection) { var mapper = EntityMappingProvider.GetMapper <TEntity>(); using (var cmd = connection.CreateCommand()) { mapper.CommandBuilder.TruncateCommand(cmd); cmd.ExecuteNonQuery(); } }
/// <summary> /// Insert an entity into the database /// </summary> /// <typeparam name="TEntity">Type of entity to load, must have an mapper registered in <see cref="EntityMappingProvider"/>.</typeparam> /// <param name="connection">Connection to use</param> /// <param name="entity">Entity to insert.</param> /// <returns>Task to wait on for completion</returns> /// <remarks> /// <para>Uses <see cref="EntityMappingProvider"/> to find the correct <c><![CDATA[ICrudEntityMapper<TEntity>]]></c></para> /// </remarks> public static async Task <object> InsertAsync <TEntity>(this IDbConnection connection, TEntity entity) { var mapper = EntityMappingProvider.GetMapper <TEntity>(); using (var cmd = connection.CreateDbCommand()) { mapper.CommandBuilder.InsertCommand(cmd, entity); return(await cmd.ExecuteScalarAsync()); } }
/// <summary> /// Update an entity /// </summary> /// <typeparam name="TEntity"> /// Type of entity to use, must have an mapper registered in <see cref="EntityMappingProvider" /> /// . /// </typeparam> /// <param name="unitOfWork">Transaction wrapper</param> /// <param name="entity">Entity to update</param> /// <returns>Task to wait on for completion</returns> /// <example> /// <code> /// using (var uow = UnitOfWorkFactory.Create()) /// { /// var user = await uow.FirstAsync(new { Id = 1 }); /// user.State = AccountState.Banned; /// await uow.UpdateAsync(user); /// /// uow.SaveChanges(); /// } /// </code> /// </example> public static async Task UpdateAsync <TEntity>(this IAdoNetUnitOfWork unitOfWork, TEntity entity) { if (unitOfWork == null) { throw new ArgumentNullException("unitOfWork"); } var mapper = EntityMappingProvider.GetMapper <TEntity>(); using (var cmd = (DbCommand)unitOfWork.CreateCommand()) { mapper.CommandBuilder.UpdateCommand(cmd, entity); await cmd.ExecuteNonQueryAsync(); } }
/// <summary> /// DELETE a row from the table. /// </summary> /// <typeparam name="TEntity">Type of entity to use, must have an mapper registered in <see cref="EntityMappingProvider"/>.</typeparam> /// <param name="connection">Unit of work to execute command in.</param> /// <param name="entity">Uses the primary key column(s), as defined in the mapping, to remove the entry.</param> /// <example> /// <code> /// <![CDATA[ /// public void DeleteUser(int userId) /// { /// connection.Delete(new User { Id = userId }); /// } /// ]]> /// </code> /// </example> public static void Delete <TEntity>(this IDbConnection connection, TEntity entity) { if (connection == null) { throw new ArgumentNullException("connection"); } var mapper = EntityMappingProvider.GetMapper <TEntity>(); using (var cmd = connection.CreateCommand()) { mapper.CommandBuilder.DeleteCommand(cmd, entity); cmd.ExecuteNonQuery(); } }
/// <summary> /// DELETE a row from the table. /// </summary> /// <typeparam name="TEntity">Type of entity to use, must have an mapper registered in <see cref="EntityMappingProvider"/>.</typeparam> /// <param name="connection">Unit of work to execute command in.</param> /// <param name="constraints"><c>dynamic</c> specifying the properties to use. All parameters are joined with "AND" in the resulting SQL query. Any parameter with '%' in the value will be using LIKE instead of '='</param> /// <example> /// <code> /// <![CDATA[ /// public void DeleteUser(int userId) /// { /// connection.Delete(new { Id = userId }); /// } /// ]]> /// </code> /// <para>Alternative syntax:</para> /// <code> /// <![CDATA[ /// public void DeleteUser(SomeDTO dto) /// { /// connection.Delete(new { dto.Id }); /// } /// ]]> /// </code> /// </example> public static void Delete <TEntity>(this IDbConnection connection, object constraints) { if (connection == null) { throw new ArgumentNullException("connection"); } var mapper = EntityMappingProvider.GetMapper <TEntity>(); using (var cmd = connection.CreateCommand()) { cmd.CommandText = "DELETE FROM " + mapper.TableName + " WHERE "; cmd.ApplyConstraints(mapper, constraints); cmd.ExecuteNonQuery(); } }