c# – 存储库模式和本地缓存
我有以下接口/类:
public interface IUnitOfWork : IDisposable { event EventHandler<EventArgs> Saved; DbSet<T> Set<T>() where T : class; DbEntityEntry<T> Entry<T>(T entity) where T : class; void Commit(); } 以及存储库的实现: public class CachedSqlRepository<T,TKey,TContext> : ICacheRepository<T,TContext> where T : class where TContext : DbContext,IDisposable,new() { //A list of the Navigation Properties to include private readonly Expression<Func<T,object>>[] _NavigationProperties; public CachedSqlRepository(params Expression<Func<T,object>>[] navigationProperties) { _NavigationProperties = navigationProperties; using (TContext dbContext = new TContext()) //Fetch the List of Entities { RefreshCache(dbContext); } } /// <summary> /// The Collection of Items in the database /// Note this is a Cache,but should replicate whats in the DB /// </summary> public IList<T> Items { get; private set; } public bool Any(Func<T,bool> predicate) { return Items.Any(predicate); } public void RefreshCache(DbContext context) { switch (_NavigationProperties.Length) { case 0: Items = context.Set<T>().ToList(); break; case 1: Items = context.Set<T>().Include(_NavigationProperties[0]).ToList(); break; //more here } } /// <summary> /// Refresh the internal cache /// </summary> public void RefreshCache() { using (TContext dbContext = new TContext()) { RefreshCache(dbContext); } } public IEnumerable<T> FilterBy(Func<T,bool> predicate) { return Items.Where(predicate); } public T Add(T entity) { T newEntity; using (TContext dbContext = new TContext()) { newEntity = dbContext.Set<T>().Add(entity); if (dbContext.SaveChanges() == 1) //1 change was made Items.Add(newEntity); } return newEntity; } public void Delete(TKey id) { using (TContext dbContext = new TContext()) { var attachedEntry = dbContext.Set<T>().Find(id); if (attachedEntry == null) return; //it doesnt exist anyway! dbContext.Set<T>().Remove(attachedEntry); dbContext.SaveChanges(); RefreshCache(dbContext); } } public void Update(T entity,TKey id) { if (entity == null) throw new ArgumentException("Cannot update a null entity."); using (TContext dbContext = new TContext()) { var entry = dbContext.Entry(entity); if (entry.State != EntityState.Detached) return; T attachedEntity = dbContext.Set<T>().Find(id); if (attachedEntity != null) { var attachedEntry = dbContext.Entry(attachedEntity); attachedEntry.CurrentValues.SetValues(entity); } else { entry.State = EntityState.Modified; // This should attach entity } dbContext.SaveChanges(); RefreshCache(dbContext); } } #region Transaction Methods public IUnitOfWork StartTransaction() { return new EFUnitOfWork(new TContext()); } public T TransactionAdd(T entity,IUnitOfWork context) { context.Saved += OnSave; return context.Set<T>().Add(entity); } public void TransactionDelete(TKey id,IUnitOfWork context) { var attachedEntry = context.Set<T>().Find(id); if (attachedEntry == null) return; //it doesnt exist anyway context.Saved += OnSave; context.Set<T>().Remove(attachedEntry); } public void TransactionUpdate(T entity,TKey id,IUnitOfWork context) { if (entity == null) throw new ArgumentException("Cannot update a null entity."); var entry = context.Entry(entity); if (entry.State != EntityState.Detached) return; T attachedEntity = context.Set<T>().Find(id); if (attachedEntity != null) { var attachedEntry = context.Entry(attachedEntity); attachedEntry.CurrentValues.SetValues(entity); } else { entry.State = EntityState.Modified; // This should attach entity } context.Saved += OnSave; } private void OnSave(object sender,EventArgs e) { RefreshCache(); } #endregion } 它改编自网上的各种图案.我不认为这对于具有数十万行的表有用,但对于查找表等 – 我并不总是打到数据库. 它可以工作,但有些东西不是很干净,例如我刷新缓存 – 有时我必须再次拉取所有数据(目前正在进行中). 这个声音设计?还是我在这里重新发明轮子? 解决方法
一个有趣的问题1.在我看来,上下文内容缓存是最好的完成或单独保留的内容.并使用DB缓存.
为什么: >并行WP都有缓存 >否:您重新加载每个请求 >您是否正确管理缓存? >您是否考虑过Context生命周期的最佳实践?一些专家建议只有短暂的寿命 在各种环境中研究了这个主题,而不仅仅是EF / .NET / SQL Server,我得出的结论是,除非DB服务器已经成为或者趋向于成为CPU瓶颈并且不能轻易扩展,否则它是一种非常合理的方法为DB提供内存并让它缓存100sMB 当每微秒计数时,或者您的数据库在网络范围内与延迟/吞吐量问题分离,并且您的数据是非易失性的,并且不需要缓存到期/并发管理.然后继续实施缓存. 仔细考虑内存使用,缓存构建时间和内存持久性模型. 查看一些用于缓存创意和潜在解决方案的工具.例如企业缓存块. 祝好运. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |