/// <summary> /// Realiza cópia da entidade. /// </summary> /// <param name="item">Item na cache.</param> /// <returns>Cópia da entidade.</returns> private static object Copiar(CacheDbItem item) { #if DEBUG Console.WriteLine("Copiando entidade " + item.ToString()); #endif DbManipulação cópia, original; original = item.Entidade; if (original is ICloneable) cópia = (DbManipulação)((ICloneable)original).Clone(); else { Type tipo = original.GetType(); cópia = (DbManipulação)tipo.Assembly.CreateInstance(tipo.FullName); foreach (FieldInfo campo in tipo.GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public)) { campo.SetValue(cópia, campo.GetValue(original)); } } #if DEBUG if (cópia == null) throw new Exception("Cópia nula!"); #endif cópia.Alterado += new DbManipulação.DbManipulaçãoHandler(item.AoAlterarEntidade); return cópia; }
/// <summary> /// Remove item do cache. /// </summary> /// <param name="entidade">Item a ser removido.</param> public void Remover(DbManipulação entidade) { CacheDbItem[] listaAntiga = new CacheDbItem[listaCache.Count]; listaCache.CopyTo(listaAntiga); if (entidade != null) { Type tipo = entidade.GetType(); foreach (CacheDbItem item in listaAntiga) /* O tipo não pode ser comparado. * Imagine que existe um item "Representante" em cache * e deseja-se remover a mesma pessoa porém "PessoaFísica" * Isso acontece na prática! */ ///if (item.Entidade != null && item.Entidade.GetType() == tipo && entidade.Referente(item.Entidade)) if (item.Entidade != null && entidade.Referente(item.Entidade)) { Remover(item); //break; /* Deve-se remover todas as instancias. * Existe caso em que há mais de uma entidade repetida na cache. * Como reproduzir ? Procure pessoa pelo codigo no atendimento faça alguma alteração e procure novamente. */ } } }
/// <summary> /// Adiciona uma entidade no cache. /// </summary> /// <param name="tipo">Tipo da entidade.</param> /// <param name="parâmetros">Parâmetros usados para recuperar a entidade.</param> /// <param name="entidade">Entidade.</param> public void Adicionar(Type tipo, object[] parâmetros, DbManipulação entidade) { CacheDbItem item; item = new CacheDbItem(entidade, ExtrairValidade(tipo), new CacheDbChave(tipo, parâmetros)); while (listaCache.Count >= tamanho) Remover(listaCache[0]); hashCache.Add(item.Chave, item); listaCache.Add(item); listaCache.Sort(); #if DEBUG //Console.WriteLine("Adicionado {0} ({1}) em cache. {2} itens em cache.", tipo.ToString(), entidade, listaCache.Count); #endif }
/// <summary> /// Remove item do cache. /// </summary> /// <param name="item">Item a ser removido.</param> private void Remover(CacheDbItem item) { #if DEBUG Console.WriteLine("Removendo da cache {0}", item.ToString()); #endif listaCache.Remove(item); hashCache.Remove(item.Chave); // Remove item da lista de referentes. if (item.Entidade != null) foreach (FieldInfo campo in item.Entidade.GetType().GetFields(BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Public)) if (campo.FieldType.IsSubclassOf(typeof(DbManipulação))) { DbManipulação obj = (DbManipulação)campo.GetValue(item.Entidade); if (obj != null && obj.PossuiReferentes) obj.Referentes.Remove(item.Entidade); } }