/// <summary> /// Performs a create for the value (reselects and/or automatically saves changes where specified). /// </summary> /// <typeparam name="T">The resultant <see cref="Type"/>.</typeparam> /// <typeparam name="TModel">The entity framework model <see cref="Type"/>.</typeparam> /// <param name="saveArgs">The <see cref="EfDbArgs{T, TModel}"/>.</param> /// <param name="value">The value to insert.</param> /// <returns>The value (refreshed where specified).</returns> public async Task <T> CreateAsync <T, TModel>(EfDbArgs <T, TModel> saveArgs, T value) where T : class, new() where TModel : class, new() { CheckSaveArgs(saveArgs); if (value == null) { throw new ArgumentNullException(nameof(value)); } if (value is IChangeLog cl) { if (cl.ChangeLog == null) { cl.ChangeLog = new ChangeLog(); } cl.ChangeLog.CreatedBy = ExecutionContext.HasCurrent ? ExecutionContext.Current.Username : ExecutionContext.EnvironmentUsername; cl.ChangeLog.CreatedDate = ExecutionContext.HasCurrent ? ExecutionContext.Current.Timestamp : DateTime.Now; } using var db = new EfDbContextManager(saveArgs); return(await EfDbInvoker <TDbContext> .Default.InvokeAsync(this, async() => { var model = saveArgs.Mapper.MapToDest(value, Mapper.OperationTypes.Create) ?? throw new InvalidOperationException("Mapping to the EF entity must not result in a null value."); db.DbContext.Add(model); if (saveArgs.SaveChanges) { await db.DbContext.SaveChangesAsync(true).ConfigureAwait(false); } return (saveArgs.Refresh) ? saveArgs.Mapper.MapToSrce(model, Mapper.OperationTypes.Get) : value; }, this).ConfigureAwait(false));
/// <summary> /// Performs a delete for the specified <paramref name="keys"/>. /// </summary> /// <typeparam name="T">The resultant <see cref="Type"/>.</typeparam> /// <typeparam name="TModel">The entity framework model <see cref="Type"/>.</typeparam> /// <param name="saveArgs">The <see cref="EfDbArgs{T, TModel}"/>.</param> /// <param name="keys">The key values.</param> public async Task DeleteAsync <T, TModel>(EfDbArgs <T, TModel> saveArgs, params IComparable[] keys) where T : class, new() where TModel : class, new() { CheckSaveArgs(saveArgs); CheckKeys(saveArgs, keys); var efKeys = new object[keys.Length]; for (int i = 0; i < saveArgs.Mapper.UniqueKey.Count; i++) { efKeys[i] = saveArgs.Mapper.UniqueKey[i].ConvertToDestValue(keys[i], Mapper.OperationTypes.Unspecified); } using (var db = new EfDbContextManager(saveArgs)) { await EfDbInvoker <TDbContext> .Default.InvokeAsync(this, async() => { // A pre-read is required to get the row version for concurrency. var em = (TModel)await db.DbContext.FindAsync(typeof(TModel), efKeys).ConfigureAwait(false); if (em == null) { return; } db.DbContext.Remove(em); if (saveArgs.SaveChanges) { await db.DbContext.SaveChangesAsync(true).ConfigureAwait(false); } }, this).ConfigureAwait(false); } }
public static IDbContext InitializeContext() { return(EfDbContextManager.GenerateContext() .SetConnectionString("name=FluentHelperExampleConnectionString") .SetLogAction(x => Console.WriteLine(x)) .AddMappingFromAssemblyOf <TestDataMap>()); }
/// <summary> /// Performs an update for the value (reselects and/or automatically saves changes where specified). /// </summary> /// <typeparam name="T">The resultant <see cref="Type"/>.</typeparam> /// <typeparam name="TModel">The entity framework model <see cref="Type"/>.</typeparam> /// <param name="saveArgs">The <see cref="EfDbArgs{T, TModel}"/>.</param> /// <param name="value">The value to insert.</param> /// <returns>The value (refreshed where specified).</returns> public async Task <T> UpdateAsync <T, TModel>(EfDbArgs <T, TModel> saveArgs, T value) where T : class, new() where TModel : class, new() { CheckSaveArgs(saveArgs); if (value == null) { throw new ArgumentNullException(nameof(value)); } if (value is IChangeLog cl) { if (cl.ChangeLog == null) { cl.ChangeLog = new ChangeLog(); } cl.ChangeLog.UpdatedBy = ExecutionContext.HasCurrent ? ExecutionContext.Current.Username : ExecutionContext.EnvironmentUsername; cl.ChangeLog.UpdatedDate = ExecutionContext.HasCurrent ? ExecutionContext.Current.Timestamp : DateTime.Now; } using (var db = new EfDbContextManager(saveArgs)) { return(await EfDbInvoker <TDbContext> .Default.InvokeAsync(this, async() => { if (OnUpdatePreReadForNotFound) { // Check (find) if the entity exists. var efKeys = new object[saveArgs.Mapper.UniqueKey.Count]; for (int i = 0; i < saveArgs.Mapper.UniqueKey.Count; i++) { var v = saveArgs.Mapper.UniqueKey[i].GetSrceValue(value, Mapper.OperationTypes.Unspecified); efKeys[i] = saveArgs.Mapper.UniqueKey[i].ConvertToDestValue(v, Mapper.OperationTypes.Unspecified); } var em = (TModel)await db.DbContext.FindAsync(typeof(TModel), efKeys).ConfigureAwait(false); if (em == null) { throw new NotFoundException(); } // Remove the entity from the tracker before we attempt to update; otherwise, will use existing rowversion and concurrency will not work as expected. db.DbContext.Remove(em); db.DbContext.ChangeTracker.AcceptAllChanges(); } var model = saveArgs.Mapper.MapToDest(value, Mapper.OperationTypes.Update); db.DbContext.Update(model); if (saveArgs.SaveChanges) { await db.DbContext.SaveChangesAsync(true).ConfigureAwait(false); } return (saveArgs.Refresh) ? saveArgs.Mapper.MapToSrce(model, Mapper.OperationTypes.Get) : value; }, this).ConfigureAwait(false)); } }
/// <summary> /// Gets the entity for the specified <paramref name="keys"/> mapping from <typeparamref name="TModel"/> to <typeparamref name="T"/>. /// </summary> /// <typeparam name="T">The resultant <see cref="Type"/>.</typeparam> /// <typeparam name="TModel">The entity framework model <see cref="Type"/>.</typeparam> /// <param name="getArgs">The <see cref="EfDbArgs{T, TModel}"/>.</param> /// <param name="keys">The key values.</param> /// <returns>The entity value where found; otherwise, <c>null</c>.</returns> public async Task <T?> GetAsync <T, TModel>(EfDbArgs <T, TModel> getArgs, params IComparable[] keys) where T : class, new() where TModel : class, new() { if (getArgs == null) { throw new ArgumentNullException(nameof(getArgs)); } CheckKeys(getArgs, keys); var efKeys = new object[keys.Length]; for (int i = 0; i < getArgs.Mapper.UniqueKey.Count; i++) { efKeys[i] = getArgs.Mapper.UniqueKey[i].ConvertToDestValue(keys[i], Mapper.OperationTypes.Unspecified) !; } using var db = new EfDbContextManager(getArgs); return(await EfDbInvoker <TDbContext> .Default.InvokeAsync(this, async() => { return await FindAsync(db, getArgs, efKeys).ConfigureAwait(false); }, this).ConfigureAwait(false)); }
/// <summary> /// Performs the EF select single (find). /// </summary> private async Task <T> FindAsync <T, TModel>(EfDbContextManager db, EfDbArgs <T, TModel> args, object[] keys) where T : class, new() where TModel : class, new() { var model = await db.DbContext.FindAsync <TModel>(keys).ConfigureAwait(false); return(args.Mapper.MapToSrce(model, Mapper.OperationTypes.Get)); }