public Dictionary <Guid, KeyValuePair <PropertyInfo, object> > AddInsertScript(StringBuilder persistScript) { Dictionary <Guid, KeyValuePair <PropertyInfo, object> > inserts = new Dictionary <Guid, KeyValuePair <PropertyInfo, object> >(); foreach (object addObj in Changes[ChangeType.Add]) { if (addObj != null) { Type addType = addObj.GetType(); if (Tables.ContainsKey(addType)) { TableData tableData = Tables[addType]; Dictionary <string, object> columnValues = tableData.ColumnMappings.Where(kvp => string.Compare(kvp.Key, tableData.KeyColumn, true) != 0) .ToDictionary(cm => cm.Key, cm => cm.Value.GetValue(addObj, null)); if (inserts.Count == 0) { persistScript.Append(SQLBuilder.OutputTableScript); } Guid insertKey = Guid.NewGuid(); persistScript.AppendLine(SQLBuilder.BuildInsert(tableData.TableName, insertKey.ToString(), tableData.KeyColumn, columnValues)); inserts.Add(insertKey, new KeyValuePair <PropertyInfo, object>(tableData.KeyProperty, addObj)); // invalidate cache data if (CachedData.ContainsKey(addType)) { CachedData.Remove(addType); } } } } if (inserts.Count > 0) { persistScript.AppendLine(SQLBuilder.OutputSelectScript); } return(inserts); }
public void Save() { using (TransactionScope transaction = new TransactionScope()) { StringBuilder persistScript = new StringBuilder(); // add insert portion to script Dictionary <Guid, KeyValuePair <PropertyInfo, object> > inserts = AddInsertScript(persistScript); #region Updates foreach (object updateObj in Changes[ChangeType.Update]) { if (updateObj != null) { Type updateType = updateObj.GetType(); if (Tables.ContainsKey(updateType)) { TableData tableData = Tables[updateType]; // Add Update script building // invalidate cache data if (CachedData.ContainsKey(updateType)) { CachedData.Remove(updateType); } } } } #endregion #region Deletes foreach (object deleteObj in Changes[ChangeType.Delete]) { if (deleteObj != null) { Type deleteType = deleteObj.GetType(); if (Tables.ContainsKey(deleteType)) { TableData tableData = Tables[deleteType]; // Add Delete script building // invalidate cache data if (CachedData.ContainsKey(deleteType)) { CachedData.Remove(deleteType); } } } } #endregion ExecutePersist(persistScript.ToString(), inserts); transaction.Complete(); } // clear out lists of changes foreach (List <object> changeList in Changes.Values) { changeList.Clear(); } }
/// <summary> /// Returns true if data was retrieved /// </summary> /// <param name="onRefreshed">true if updated, false if from cache</param> public async Task <bool> WithRefreshAsync <T>(RequestToken token, string key, bool allowStaleData, bool forceRefresh, FetchedRequestDelegate <T> onRefreshed, Action <bool> onRefreshing, Func <Task <T> > createMethod) where T : class { this.EnsureInitialized(); IDataCacheFilter[] filters = this.Filters.Values.ToArray(); // see if we can use old data bool canReadCached = true; foreach (var item in filters) { if (!item.CanReadCached(this, key)) { canReadCached = false; break; } } T foundData = null; // use old data if we can if (allowStaleData && canReadCached && CachedData.ContainsKey(key)) { foundData = CachedData[key] as T; if (foundData == null) { forceRefresh = true; //had it, but it was bad data } } // see if we need to refresh if (!forceRefresh) { foreach (var item in filters) { if (item.RefreshRequired(this, key)) { forceRefresh = true; break; } } } if (foundData != null) { if (onRefreshed != null) { try { onRefreshed(token, false, foundData); // its not fresh } catch (Exception ex) { this.LogError(ex, "onRefreshed:old"); } } } // get the data if we need to if (foundData == null || forceRefresh || !canReadCached || !CachedData.ContainsKey(key)) { // single request at a time lock (_ExecutingLock) { if (this.Executing.Contains(key)) { return(false); } this.Executing.Add(key); } try { // get the data foreach (var item in filters) { item.OnBeforeItemRetrieved(this, key); } if (onRefreshing != null) { try { onRefreshing(true); } catch (Exception ex) { this.LogError(ex, "onRefreshing:true"); } } T data = null; if (createMethod != null) { data = await createMethod(); } foreach (var item in filters) { item.OnAfterItemRetrieved(this, key, data); } if (data != null) { bool canWriteToCache = true; foreach (var item in filters) { if (!item.CanSaveToCache(this, key, data)) { canWriteToCache = false; break; } } if (canWriteToCache) { foreach (var item in filters) { item.OnBeforeItemSavedToCache(this, key, data); } this.AddToCache(key, data); foreach (var item in filters) { item.OnAfterItemSavedToCache(this, key, data); } } if (onRefreshed != null) { try { onRefreshed(token, true, data); } catch (Exception ex) { this.LogError(ex, "onRefreshed:new"); } } return(true); } else { return(false); } } finally { lock (_ExecutingLock) { this.Executing.Remove(key); } if (onRefreshing != null) { try { onRefreshing(false); } catch (Exception ex) { this.LogError(ex, "onRefreshing:false"); } } } } else { if (onRefreshing != null) { try { onRefreshing(false); } catch (Exception ex) { this.LogError(ex, "onRefreshing:false"); } } return(false); } }