/// <summary> /// Обновляет кэш отсутвующих /// </summary> /// <param name="query"></param> /// <param name="options"></param> /// <param name="connection"></param> protected long[] UpdateCache(string query, ObjectDataCacheHints options = null, IDbConnection connection = null) { lock (_nativeCache){ var allids = new List <long>(); bool cascade = true; if (null == connection) { if (string.IsNullOrWhiteSpace(ConnectionString)) { UpdateSingleQuery(query, options, null, allids, cascade); } else { //no self created using (var c = ConnectionProvider.GetConnection(ConnectionString)){ if (string.IsNullOrWhiteSpace(c.ConnectionString)) { throw new Exception("bad connection!"); } UpdateSingleQuery(query, options, c, allids, cascade); c.Close(); } } } else { UpdateSingleQuery(query, options, connection, allids, cascade); } return(allids.ToArray()); } }
/// <summary> /// Возвращает сущность по коду или ID /// </summary> /// <param name="key"></param> /// <param name="connection"></param> /// <param name="options"></param> /// <returns></returns> public T Get(object key, IDbConnection connection = null, ObjectDataCacheHints options = null) { options = options ?? ObjectDataCacheHints.Empty; int id; string code; var isid = IsId(key, out id, out code); if (isid) { if (!_nativeCache.ContainsKey(id) || options.ForceUpdate) { UpdateCache("(Id = " + id + ")", connection: connection, options: new ObjectDataCacheHints { KeyQuery = true, Key = id }); } if (!_nativeCache.ContainsKey(id)) { _nativeCache[id] = null; } return(_nativeCache[id]); } else { if (!_nativeCodeCache.ContainsKey(code) || options.ForceUpdate) { UpdateCache("(Code = '" + code.ToSqlString() + "')", connection: connection, options: new ObjectDataCacheHints { KeyQuery = true, Key = code }); } if (!_nativeCodeCache.ContainsKey(code)) { _nativeCodeCache[code] = null; } return(_nativeCodeCache[code]); } }
/// <summary> /// Возвращает все по запросу /// </summary> /// <param name="query"></param> /// <param name="options"></param> /// <param name="connection"></param> /// <returns></returns> public T[] GetAll(object query = null, IDbConnection connection = null, ObjectDataCacheHints options = null) { options = options ?? ObjectDataCacheHints.Empty; if (null == query || (query is string && string.IsNullOrWhiteSpace((string)query))) { if (_allLoadWasCalled) { return(_nativeCache.Values.ToArray()); } UpdateCache("", options, connection); _allLoadWasCalled = true; return(_nativeCache.Values.ToArray()); } var nativequery = query as Func <T, bool>; if (null != nativequery) { return(_nativeCache.Values.Where(nativequery).ToArray()); } var ids = UpdateCache(query as string, options, connection); return(ids.Select(_ => _nativeCache[_]).ToArray()); }
/// <summary> /// Выполняет действия после обновления кэша с учетом текущего соединения для оптимизации, /// позволяет донастроить кастомные биндинги и увязки с моделью /// </summary> /// <param name="ids"></param> /// <param name="dbConnection"></param> /// <param name="context"></param> protected virtual void AfterUpdateCache(IList <long> ids, IDbConnection dbConnection, ObjectDataCacheHints context) { if (null != OnAfterUpdateCache) { OnAfterUpdateCache.Invoke(this, ids, dbConnection, context); } }
/// <summary> /// Низкоуровневый метод обновления после запроса /// </summary> /// <param name="query"></param> /// <param name="options"></param> /// <param name="c"></param> /// <param name="allids"></param> /// <param name="cascade"></param> public List <long> UpdateSingleQuery(string query, ObjectDataCacheHints options, IDbConnection c, List <long> allids, bool cascade) { options = options ?? ObjectDataCacheHints.Empty; object eq = query; if (options.KeyQuery) { eq = options.Key; var external = GetByExternals(eq); if (null != external) { Set(external); var exids = new[] { ((IWithId)external).Id }; if (cascade) { AfterUpdateCache(exids, c, new ObjectDataCacheHints { NoChildren = true }); } return(exids.ToList()); } } else { var externals = FindByExternals(eq).ToArray(); if (externals.Any()) { var exarray = externals.ToArray(); foreach (var e in externals.ToArray()) { Set(e); } var exids = exarray.OfType <IWithId>().Select(_ => _.Id).ToArray(); if (cascade) { AfterUpdateCache(exids, c, new ObjectDataCacheHints { NoChildren = true }); } return(exids.ToList()); } } allids = allids ?? new List <long>(); if (null == c) { return(allids); } var q = query; if (!q.Contains("from")) { q = "select Id from " + Adapter.GetTableName(); if (!string.IsNullOrWhiteSpace(query)) { q += " where " + query; } } if (string.IsNullOrWhiteSpace(c.ConnectionString)) { throw new Exception("bad connection string!!!"); } c.WellOpen(); var cmd = c.CreateCommand(q); var ids = new List <long>(); SqlLog.Trace(q); using (var idsReader = cmd.ExecuteReader()){ while (idsReader.Read()) { var id = Convert.ToInt64(idsReader.GetValue(0)); if (!_nativeCache.ContainsKey(id)) { ids.Add(id); } if (!allids.Contains(id)) { allids.Add(id); } } } if (ids.Count != 0) { q = "(Id in (" + string.Join(",", ids) + "))"; cmd = c.CreateCommand(Adapter.PrepareSelectQuery(q)); SqlLog.Trace(cmd.CommandText); using (var reader = cmd.ExecuteReader()){ var items = Adapter.ProcessRecordSet(reader, true).ToArray(); foreach (var item in items) { Set(item); } } if (cascade) { AfterUpdateCache(ids, c, options); } } return(allids); }