/// <summary> /// EF DbContext.SaveChanges() - Saves the object to the database /// </summary> public override int SaveChanges() { var returnValue = TypeExtension.DefaultInteger; try { // Save returnValue = base.SaveChanges(); // Clear DbSet tracking foreach (var x in this.Set <TEntity>()) { Entry(x).State = System.Data.Entity.EntityState.Detached; } this.Set <TEntity>().Load(); } catch (Exception ex) { ExceptionLogger.Create(ex, typeof(TEntity), String.Format("SaveableDatabase.SaveChanges() on {0}", this.ToString())); if (ThrowException == true) { throw; } } return(returnValue); }
/// <summary> /// Gets database record with exact Key match /// </summary> /// <param name="key">Database Key of the record to pull</param> /// <returns>Single entity that matches by Key, or an empty entity for not found</returns> public TEntity GetByKey(Guid key) { var returnValue = new TEntity(); try { returnValue = Data.Where(x => x.Key == key).FirstOrDefaultSafe(); } catch (Exception ex) { ExceptionLogger.Create(ex, typeof(TEntity), "ReadOnlyDatabase.GetByKey()"); } return(returnValue); }
/// <summary> /// All data in this datastore subset, except records with default ID/Key /// Criteria: Where ID != TypeExtension.DefaultInteger And Also Key != TypeExtension.DefaultGuid /// Goal: To exclude "Not Selected" records from lookup tables /// </summary> public IQueryable <TEntity> GetAllExcludeDefault() { var returnValue = default(IQueryable <TEntity>); try { returnValue = Data.Where(x => x.ID != TypeExtension.DefaultInteger && x.Key != TypeExtension.DefaultGuid); } catch (Exception ex) { ExceptionLogger.Create(ex, typeof(TEntity), "ReadOnlyDatabase.GetAllExcludeDefault()"); } return(returnValue); }
/// <summary> /// All data in this datastore subset /// Can add clauses, such as GetAll().Take(1), GetAll().Where(), etc. /// </summary> public IQueryable <TEntity> GetAll() { var returnValue = default(IQueryable <TEntity>); try { returnValue = Data; } catch (Exception ex) { ExceptionLogger.Create(ex, typeof(TEntity), "ReadOnlyDatabase.GetAll()"); } return(returnValue); }
/// <summary> /// Retrieves data with purpose of displaying results over multiple pages (i.e. in Grid/table) /// </summary> /// <param name="whereClause">Expression for where clause</param> /// <returns></returns> public IQueryable <TEntity> GetByWhere(Expression <Func <TEntity, Boolean> > whereClause) { var db = ReadOnlyDatabase <TEntity> .Construct(); var returnValue = default(IQueryable <TEntity>); try { returnValue = (whereClause != null) ? db.Data.Where <TEntity>(whereClause) : db.Data; } catch (Exception ex) { ExceptionLogger.Create(ex, typeof(TEntity), "ReadOnlyDatabase.GetByWhere()"); } return(returnValue); }
/// <summary> /// Worker that deletes this object with automatic tracking /// </summary> /// <param name="entity">Entity to be removed from the datastore</param> /// <returns>True if record deleted, false if not</returns> public virtual bool Delete(TEntity entity) { var returnValue = TypeExtension.DefaultBoolean; try { if (entity.ID != TypeExtension.DefaultInteger) { if (ActivityLogger.GetByID(entity.ActivityContextID, ConnectionStringName.DefaultValue, DatabaseSchemaName.DefaultActivityValue).ActivityContextID == TypeExtension.DefaultInteger) { entity.ActivityContextID = ActivityLogger.Create(ConnectionStringName.DefaultValue, DatabaseSchemaName.DefaultActivityValue); } // All database commits require activity of some sort if ((this.DataAccessBehavior() == DataAccessBehaviors.InsertOnly) & (this.DataAccessBehavior() == DataAccessBehaviors.SelectOnly)) { if (ThrowException) { throw new System.Exception("Deletes not allowed."); } } this.Data.Remove(this.Data.Where(x => x.ID == entity.ID).FirstOrDefaultSafe()); this.SaveChanges(); } else { this.Fill(new TEntity()); } returnValue = true; } catch (Exception ex) { returnValue = false; #if DEBUG System.Diagnostics.Debugger.Break(); #endif ExceptionLogger.Create(ex, typeof(TEntity), String.Format("WriteConnection.Delete() on {0}", this.ToString())); if (ThrowException) { throw; } } return(returnValue); }
/// <summary> /// Retrieves data with purpose of displaying results over multiple pages (i.e. in Grid/table) /// </summary> /// <param name="whereClause">Expression for where clause</param> /// <param name="orderByClause">Expression for order by clause</param> /// <param name="pageSize">Size of each result</param> /// <param name="pageNumber">Page number</param> /// <returns></returns> public IQueryable <TEntity> GetByPage(Expression <Func <TEntity, Boolean> > whereClause, Expression <Func <TEntity, Boolean> > orderByClause, int pageSize, int pageNumber) { var db = ReadOnlyDatabase <TEntity> .Construct(); var datastore = ReadOnlyDatabase <TEntity> .Construct(); var returnValue = default(IQueryable <TEntity>); try { returnValue = (datastore.Data).AsQueryable(); returnValue = (whereClause != null) ? returnValue.Where <TEntity>(whereClause).AsQueryable() : returnValue; returnValue = (orderByClause != null) ? returnValue.OrderBy(orderByClause).AsQueryable() : returnValue; returnValue = (pageNumber > 0 && pageSize > 0) ? returnValue.Skip((pageNumber * pageSize)).Take(pageSize).AsQueryable() : returnValue; } catch (Exception ex) { ExceptionLogger.Create(ex, typeof(TEntity), "ReadOnlyDatabase.GetByPage()"); } return(returnValue); }
/// <summary> /// Worker that saves this object with automatic tracking. /// </summary> /// <param name="entity">Entity to be committed to the datastore</param> /// <param name="forceInsert">Ability to override insert vs. update and force insert</param> public virtual TEntity Save(TEntity entity, bool forceInsert) { var returnValue = new TEntity(); var connectionName = this.GetAttributeValue <ConnectionStringName>(ConnectionStringName.DefaultValue); var activitySchema = this.GetAttributeValue <DatabaseSchemaName>(DatabaseSchemaName.DefaultValue); var activity = new ActivityContext(); try { activity = ActivityLogger.GetByID(entity.ActivityContextID, connectionName, activitySchema); if (entity.Equals(returnValue) == false) { if (activity.ActivityContextID == TypeExtension.DefaultInteger) { entity.ActivityContextID = ActivityLogger.Create(connectionName, activitySchema); } if (entity.IsNew == true || forceInsert == true || this.DataAccessBehavior() == DataAccessBehaviors.InsertOnly) { if (this.DataAccessBehavior() == DataAccessBehaviors.SelectOnly) { if (ThrowException) { throw new System.Exception(String.Format("{0}: {1}", this.GetType().ToStringSafe(), "Inserts not allowed.")); } } this.Data.Add((TEntity)entity); } else { if ((this.DataAccessBehavior() != DataAccessBehaviors.AllAccess) | (this.DataAccessBehavior() == DataAccessBehaviors.NoUpdate)) { if (ThrowException) { throw new System.Exception(String.Format("{0}: {1}", this.GetType().ToStringSafe(), "Updates not allowed.")); } } returnValue = this.Data.Find(entity.ID); // Overlay new data onto existing DB record to establish correct context returnValue?.Fill((TEntity)entity); } entity.ValidateAll(entity); if (entity.CanSave(entity) == true) { this.SaveChanges(); } returnValue = GetByID(entity.ID); // Re-pull clean object, exactly as the DB has stored entity.Key = returnValue.Key; // ID auto updates object from SP, Key is not updated. Sync Key between return object and passed object. } } catch (Exception ex) { #if DEBUG System.Diagnostics.Debugger.Break(); #endif ExceptionLogger.Create(ex, typeof(TEntity), String.Format("{0} SaveableDatabase.Save()", this.GetType().ToStringSafe())); if (ThrowException) { throw; } } finally { returnValue = returnValue ?? entity; } return(returnValue); }