我有自己的存储库,如下所示.但是,这并未考虑一些新功能,例如范围功能.有没有人有一个包含所有内容的存储库.我在网上搜索过这个,但是我找不到最新的东西.这就是我所拥有的.我希望有更多的东西,并提供许多方法的IQueryable:
namespace Services.Repositories { ////// The EF-dependent, generic repository for data access /// ///Type of entity for this Repository. public class GenericRepository: IRepository where T : class { public GenericRepository(DbContext dbContext) { if (dbContext == null) throw new ArgumentNullException("An instance of DbContext is required to use this repository", "context"); DbContext = dbContext; DbSet = DbContext.Set (); } protected DbContext DbContext { get; set; } protected DbSet DbSet { get; set; } public virtual IQueryable Find(Expression > predicate) { return DbSet.Where (predicate); } public virtual IQueryable GetAll() { return DbSet; } public virtual T GetById(int id) { //return DbSet.FirstOrDefault(PredicateBuilder.GetByIdPredicate (id)); return DbSet.Find(id); } public virtual void Add(T entity) { DbEntityEntry dbEntityEntry = DbContext.Entry(entity); if (dbEntityEntry.State != EntityState.Detached) { dbEntityEntry.State = EntityState.Added; } else { DbSet.Add(entity); } } public virtual void Update(T entity) { DbEntityEntry dbEntityEntry = DbContext.Entry(entity); if (dbEntityEntry.State == EntityState.Detached) { DbSet.Attach(entity); } dbEntityEntry.State = EntityState.Modified; } public virtual void Delete(T entity) { DbEntityEntry dbEntityEntry = DbContext.Entry(entity); if (dbEntityEntry.State != EntityState.Deleted) { dbEntityEntry.State = EntityState.Deleted; } else { DbSet.Attach(entity); DbSet.Remove(entity); } } public virtual void Delete(int id) { var entity = GetById(id); if (entity == null) return; // not found; assume already deleted. Delete(entity); } } }
Colin.. 14
您可以添加以下新功能:
public virtual void AddRange(IEnumerableentities) { DbContext.Set ().AddRange(entities); } public virtual void RemoveRange(IEnumerable entities) { DbContext.Set ().RemoveRange(entities); }
danludwig.. 10
您不需要通用存储库.DbContext已经是一个通用的存储库.试试这个:
public class EntityDbContext : DbContext, IWriteEntities { public IQueryableEagerLoad (IQueryable query, Expression > expression) { // Include will eager load data into the query if (query != null && expression != null) query = query.Include(expression); return query; } public IQueryable Query () { // AsNoTracking returns entities that are not attached to the DbContext return Set ().AsNoTracking(); } public TEntity Get (object firstKeyValue, params object[] otherKeyValues) { if (firstKeyValue == null) throw new ArgumentNullException("firstKeyValue"); var keyValues = new List
...如果您需要将UoW与命令中的查询分开,那么接口只是一种形式:
public interface IUnitOfWork { int SaveChanges(); TaskSaveChangesAsync(); Task DiscardChangesAsync(); void DiscardChanges(); } public interface IReadEntities { IQueryable Query (); IQueryable EagerLoad (IQueryable query, Expression > expression); } public interface IWriteEntities : IUnitOfWork, IReadEntities { TEntity Get (object firstKeyValue, params object[] otherKeyValues); Task GetAsync (object firstKeyValue, params object[] otherKeyValues); IQueryable Get (); void Create (TEntity entity); void Delete (TEntity entity); void Update (TEntity entity); void Reload (TEntity entity); Task ReloadAsync (TEntity entity); }
有了这个,您的接口不需要是通用的,因为这些方法是通用的.
private readonly IWriteEntities _entities; ... _entities.Get(keyA); await _entities.GetAsync (keyB); _entities.Get .Where(... var results = await _entities.Query ().SingleOrDefaultAsync(...
您刚刚在上面的代码中保存了3个不必要的通用存储库依赖项.一个界面可以处理所有4种权利类型.
您不需要通用存储库.DbContext已经是一个通用的存储库.试试这个:
public class EntityDbContext : DbContext, IWriteEntities { public IQueryable<TEntity> EagerLoad<TEntity>(IQueryable<TEntity> query, Expression<Func<TEntity, object>> expression) { // Include will eager load data into the query if (query != null && expression != null) query = query.Include(expression); return query; } public IQueryable<TEntity> Query<TEntity>() { // AsNoTracking returns entities that are not attached to the DbContext return Set<TEntity>().AsNoTracking(); } public TEntity Get<TEntity>(object firstKeyValue, params object[] otherKeyValues) { if (firstKeyValue == null) throw new ArgumentNullException("firstKeyValue"); var keyValues = new List<object> { firstKeyValue }; if (otherKeyValues != null) keyValues.AddRange(otherKeyValues); return Set<TEntity>().Find(keyValues.ToArray()); } public Task<TEntity> GetAsync<TEntity>(object firstKeyValue, params object[] otherKeyValues) { if (firstKeyValue == null) throw new ArgumentNullException("firstKeyValue"); var keyValues = new List<object> { firstKeyValue }; if (otherKeyValues != null) keyValues.AddRange(otherKeyValues); return Set<TEntity>().FindAsync(keyValues.ToArray()); } public IQueryable<TEntity> Get<TEntity>() { return Set<TEntity>(); } public void Create<TEntity>(TEntity entity) { if (Entry(entity).State == EntityState.Detached) Set<TEntity>().Add(entity); } public void Update<TEntity>(TEntity entity) { var entry = Entry(entity); entry.State = EntityState.Modified; } public void Delete<TEntity>(TEntity entity) { if (Entry(entity).State != EntityState.Deleted) Set<TEntity>().Remove(entity); } public void Reload<TEntity>(TEntity entity) { Entry(entity).Reload(); } public Task ReloadAsync<TEntity>(TEntity entity) { return Entry(entity).ReloadAsync(); } public void DiscardChanges() { foreach (var entry in ChangeTracker.Entries().Where(x => x != null)) { switch (entry.State) { case EntityState.Added: entry.State = EntityState.Detached; break; case EntityState.Modified: entry.State = EntityState.Unchanged; break; case EntityState.Deleted: entry.Reload(); break; } } } public Task DiscardChangesAsync() { var reloadTasks = new List<Task>(); foreach (var entry in ChangeTracker.Entries().Where(x => x != null)) { switch (entry.State) { case EntityState.Added: entry.State = EntityState.Detached; break; case EntityState.Modified: entry.State = EntityState.Unchanged; break; case EntityState.Deleted: reloadTasks.Add(entry.ReloadAsync()); break; } } return Task.WhenAll(reloadTasks); } }
...如果您需要将UoW与命令中的查询分开,那么接口只是一种形式:
public interface IUnitOfWork { int SaveChanges(); Task<int> SaveChangesAsync(); Task DiscardChangesAsync(); void DiscardChanges(); } public interface IReadEntities { IQueryable<TEntity> Query<TEntity>(); IQueryable<TEntity> EagerLoad<TEntity>(IQueryable<TEntity> query, Expression<Func<TEntity, object>> expression); } public interface IWriteEntities : IUnitOfWork, IReadEntities { TEntity Get<TEntity>(object firstKeyValue, params object[] otherKeyValues); Task<TEntity> GetAsync<TEntity>(object firstKeyValue, params object[] otherKeyValues); IQueryable<TEntity> Get<TEntity>(); void Create<TEntity>(TEntity entity); void Delete<TEntity>(TEntity entity); void Update<TEntity>(TEntity entity); void Reload<TEntity>(TEntity entity); Task ReloadAsync<TEntity>(TEntity entity); }
有了这个,您的接口不需要是通用的,因为这些方法是通用的.
private readonly IWriteEntities _entities; ... _entities.Get<MyEntityA>(keyA); await _entities.GetAsync<MyEntityB>(keyB); _entities.Get<MyEntityC>.Where(... var results = await _entities.Query<MyEntityD>().SingleOrDefaultAsync(...
您刚刚在上面的代码中保存了3个不必要的通用存储库依赖项.一个界面可以处理所有4种权利类型.
您可以添加以下新功能:
public virtual void AddRange(IEnumerable<T> entities) { DbContext.Set<T>().AddRange(entities); } public virtual void RemoveRange(IEnumerable<T> entities) { DbContext.Set<T>().RemoveRange(entities); }