/// <summary> /// Adds or updates an entity in the database from a ViewModel, only if a certain condition is satisfied. The Entity class needs to implement IPersistableObj interface. /// </summary> /// <typeparam name="TViewModel">View model type</typeparam> /// <typeparam name="TDbSet">Base entity type (i.e DbSet type)</typeparam> /// <typeparam name="TEntity">Entity type</typeparam> /// <param name="set">Entity data set (e.g. Context.Drills)</param> /// <param name="viewModel">View model instance</param> /// <param name="filter">Condition to be satisfied [e.g (UserDrill d) => d.AccountId == 5]</param> /// <param name="key">Entity key value</param> /// <param name="includes">Includes needed to map the entity to the view model type.</param> /// <returns>The saved entity mapped to the view model type or null if the condition is not satisfied.</returns> public static TViewModel SaveIfAllowed <TViewModel, TDbSet, TEntity>(this DbContext context, TViewModel viewModel, Expression <Func <TEntity, bool> > filter, object[] keyValues, Func <IQueryable <TEntity>, IQueryable <TEntity> > includes = null) where TDbSet : class where TEntity : class, TDbSet, new() { var set = context.Set <TDbSet>(); keyValues = keyValues ?? ArrayExtensions.EmptyArray <object>(); var metadata = PrimaryKeysMetadataFactory <TEntity> .GetForContext(context); var entity = keyValues.Length > 0 ? set.OfType <TEntity>().Where(metadata.GetKeysFilter(keyValues)) .ApplyIncludes(includes) .FirstOrDefault() : null; if (entity == null) { using (var tr = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = IsolationLevel.ReadCommitted }, TransactionScopeAsyncFlowOption.Enabled)) { entity = set.Create <TEntity>(); Mapper.Map(viewModel, entity); set.Add(entity); context.SaveChanges(); var newKeys = metadata.GetPrimaryKeys(entity); //apply filter on newly added entity. var savedData = set.OfType <TEntity>().Where(metadata.GetKeysFilter(newKeys)).Where(filter) .ApplyIncludes(includes) .FirstOrDefault(); if (savedData == null) { return(default(TViewModel)); } tr.Complete(); } } else { var allowed = set.OfType <TEntity>().Where(metadata.GetKeysFilter(keyValues)).Where(filter).Any(); if (!allowed) { return(default(TViewModel)); } Mapper.Map(viewModel, entity); context.SaveChanges(); } // map back to viewModel (to get any identity column inserted ID) Mapper.Map(entity, viewModel); return(viewModel); }
public static object[] GetPrimaryKeys <TEntity>(this DbContext context, TEntity entity) where TEntity : class { if (entity == null) { return(ArrayExtensions.EmptyArray <object>()); } var metadata = PrimaryKeysMetadataFactory <TEntity> .GetForContext(context); return(metadata.GetPrimaryKeys(entity)); }
public static Expression <Func <TEntity, bool> > GetPrimaryKeysFilter <TEntity>(this DbContext context, object[] keyValues) where TEntity : class { var metadata = PrimaryKeysMetadataFactory <TEntity> .GetForContext(context); return(metadata.GetKeysFilter(keyValues)); }