Skip to content

Instantly share code, notes, and snippets.

@jpolvora
Created July 28, 2013 14:49
Show Gist options
  • Save jpolvora/6098848 to your computer and use it in GitHub Desktop.
Save jpolvora/6098848 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DbContextCaching {
public class EntityBase {
[Key]
public int Id { get; set; }
public DateTime DataCadastro { get; set; }
public DateTime DataAlteracao { get; set; }
}
public class Usuario : EntityBase {
[StringLength(50)]
public string Nome { get; set; }
public override string ToString() {
return string.Format("{0} -{1}", Id, Nome);
}
}
public class TesteContextInitializer : CreateDatabaseIfNotExists<TesteContext> {
protected override void Seed(TesteContext context) {
var usuario = new Usuario {
Nome = "Teste"
};
context.Usuarios.Add(usuario);
base.Seed(context);
}
}
public class TesteContext : DbContext {
static readonly TesteContext _InternalCache = new TesteContext();
public static TesteContext InternalCache {
get { return _InternalCache; }
}
static TesteContext() {
Database.SetInitializer(new TesteContextInitializer());
}
public DbSet<Usuario> Usuarios { get; set; }
public override int SaveChanges() {
var entities = ChangeTracker.Entries<EntityBase>();
foreach (var entry in entities) {
switch (entry.State) {
case EntityState.Added: {
entry.Entity.DataCadastro = DateTime.Now;
entry.Entity.DataAlteracao = DateTime.Now;
break;
}
case EntityState.Modified: {
entry.Property(x => x.DataCadastro).IsModified = false;
entry.Entity.DataAlteracao = DateTime.Now;
break;
}
}
}
//cache para usuários
foreach (var dbEntityEntry in ChangeTracker.Entries<Usuario>()) {
DbEntityEntry<Usuario> entry = dbEntityEntry;
var cachedEntry = _InternalCache.ChangeTracker.Entries<Usuario>().FirstOrDefault(x => x.Entity.Id == entry.Entity.Id);
if (cachedEntry != null)
cachedEntry.State = EntityState.Detached;
}
return base.SaveChanges();
}
}
class Program {
static void Main(string[] args) {
using (var ctx = new TesteContext()) {
ctx.Database.Initialize(false);
}
using (var ctx = new TesteContext()) {
foreach (var usuario in ctx.Usuarios) {
Console.WriteLine(usuario);
Console.WriteLine("Data de Modificação: {0}", usuario.DataAlteracao);
}
}
//coloca o usuário no cache
var cachedUsuario = TesteContext.InternalCache.Usuarios.FirstOrDefault();
Console.WriteLine("Colocar o usuário no cache: {0} ", cachedUsuario);
//verifica se está no cache realmente
var testeCachedUsuario = TesteContext.InternalCache.Usuarios.Local.FirstOrDefault();
Console.WriteLine("Usuário verificado no cache: {0} ", testeCachedUsuario);
//compara as instâncias
Debug.Assert(cachedUsuario == testeCachedUsuario);
Console.WriteLine("{0} comparado com {1} ", cachedUsuario, testeCachedUsuario);
//para remover do cache, basta alterar o usuário
using (var ctx = new TesteContext()) {
var usuario = ctx.Usuarios.First();
usuario.Nome = Guid.NewGuid().ToString().Substring(0, 10);
ctx.SaveChanges();
Console.WriteLine("Usuário alterado normalmente: {0} / {1}", usuario, usuario.DataAlteracao);
}
//testa novamente o usuário no cache
var novoTesteCachedUsuario = TesteContext.InternalCache.Usuarios.Local.FirstOrDefault();
Debug.Assert(novoTesteCachedUsuario == null);
Console.WriteLine("Usuário saiu do cache {0}", novoTesteCachedUsuario);
var normal =
TesteContext.InternalCache.Usuarios.Local.FirstOrDefault() ??
TesteContext.InternalCache.Usuarios.FirstOrDefault();
Console.WriteLine("Usuário recuperado {0}", normal);
Console.ReadLine();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment