private SaveModel BuildSaveModel(SaveWorkState saveWorkState) { SaveModel saveModel = new SaveModel(this.context); foreach (var kvp in saveWorkState.SaveMap) { Type entityType = kvp.Key; List <EntityInfo> entityInfos = kvp.Value; saveModel.AddRange(entityType, entityInfos); } return(saveModel); }
private void ExecuteSaveHandlers(SaveModel saveModel) { List <ISaveHandler> saveHandlers = CreateSaveHandlers(); foreach (ISaveHandler saveHandler in saveHandlers) { SaveEntitySet saveEntitySet = saveModel.GetEntitySet(saveHandler.EntityType); if (saveEntitySet != null) { foreach (SaveEntity saveEntity in saveEntitySet) { saveHandler.Save(saveEntity); } } } }
protected virtual void ValidateSaveState(SaveModel saveModel) { foreach (SaveEntitySet saveEntitySet in saveModel.GetEntitySets()) { foreach (SaveEntity saveEntity in saveEntitySet) { // Check that all added/deleted entities have been processed // TODO: Have they? // Check that all property values have been processed foreach (SaveProperty saveProperty in saveEntity.Properties) { if (saveProperty.State == SavePropertyState.Pending && !saveProperty.IsNewValueEqual(saveEntity.Entity)) { throw new Exception("Property value was not saved by a SaveHandler."); } } } } }
protected override void SaveChangesCore(SaveWorkState saveWorkState) { SaveModel saveModel = BuildSaveModel(saveWorkState); LoadEntities(saveModel); ExecuteSaveHandlers(saveModel); ValidateSaveState(saveModel); try { this.Context.SaveChanges(); } catch (DbEntityValidationException e) { // TODO: Set saveWorkState.EntityErrors throw new NotImplementedException(); } // TODO: Set saveWorkState.KeyMappings // TODO: Update saveWorkState entities from the ones in this.Context }
protected virtual void LoadEntities(SaveModel saveModel) { foreach (SaveEntitySet saveEntitySet in saveModel.GetEntitySets()) { Type entityType = saveEntitySet.EntityType; ApiEntityTypeConfiguration entityTypeConfig; if (!this.Model.TryGetEntityTypeConfig(entityType, out entityTypeConfig)) { throw new Exception("Entity type not supported."); } object resource = this.resources[entityTypeConfig.ResourceType]; IQueryable queryable = (IQueryable)entityTypeConfig.ResourceAccessor.DynamicInvoke(resource); // TODO: It's not always int IDs PropertyInfo idPropertyInfo = entityType.GetProperty("Id"); List <int> ids = saveEntitySet.Where(m => !m.IsAdded).Select( m => (int)idPropertyInfo.GetValue(m.EntityInfo.Entity)).ToList(); var arg = Expression.Parameter(entityType, "p"); var body = Expression.Call(Expression.Constant(ids), "Contains", null, Expression.Property(arg, "Id")); var predicate = Expression.Lambda(body, arg); var where = Expression.Call(typeof(Queryable), "Where", new Type[] { queryable.ElementType }, queryable.Expression, Expression.Quote(predicate)); foreach (object entity in queryable.Provider.CreateQuery(where)) { int id = (int)idPropertyInfo.GetValue(entity); SaveEntity saveEntity = saveEntitySet.First(m => (int)idPropertyInfo.GetValue(m.EntityInfo.Entity) == id); saveEntity.Entity = entity; } } }