关键词:
【中文标题】具有 EntityFramework 的通用存储库【英文标题】:Generic Repository with EntityFramework 【发布时间】:2017-08-07 10:45:53 【问题描述】:我想使用实体框架实现一个通用的存储库模式(我知道关于存储库有很多有争议的观点,但这仍然是我需要的)。 我想要的界面如下:
public interface IRepository
IQueryable<TEntity> Query<TEntity>()
where TEntity: Entity;
void Save<TEntity>(TEntity entity)
where TEntity : Entity;
void Delete<TEntity>(TEntity entity)
where TEntity : Entity;
Entity
是一个只有int ID
属性的基类。
并像这样使用它:
IRepository repository = ... // get repository (connects to DB)
int userId = GetCurrentUserId();
if (!repository.Query<User>().Any(u => u.Id == userId)) // performs SELECT query
/*return error*/
var newOrder = new Order UserId = userId, Status = "New"
repository.Save(newOrder); // performs INSERT query
...
newOrder.Status = "Completed";
repository.Save(newOrder); // performs UPDATE query
我想避免UnitOwWork
,只要调用Save()
或Delete()
就将所有对象更改提交到数据库。我想做的事情看起来很简单,但我没有找到任何使用 EntityFramework 的示例。我能找到的最接近的示例是 this answer,但它使用 UnitOwWork
和 repository-per-entity,其中比我需要做的更复杂。
【问题讨论】:
如果你想保持简单,那么不要在实体框架中使用存储库模式。实体框架本身已经是一个存储库模式,您只是在现有抽象之上添加更多抽象,它没有任何好处。相反,它可能会使您的代码更难维护和使用,同时增加开发额外不必要层的成本。 这不是一个通用存储库,它只是一个 DbContext 的包装器。我很好奇您是如何实现Save
的,因为它表明您可以有选择地保存一个实体,即使上下文包含更多已更改的实体。难以置信。如果可以的话,这违背了SaveChanges
方法的目的。
@GertArnold,接口是一个存储库。我已经使用纯 ADO.NET 和 Dapper 实现了其中的一部分。 (顺便说一句,这是我想要对 EF 进行抽象的原因之一:我的应用程序的某些部分包含 EF 不完全支持的复杂查询,但我希望使用一个抽象来执行所有查询:IRepository)IRepository 不知道或关心 EF 或 DbContext。它应该是所有数据操作的通用简单接口(这在后台可能非常复杂 - 就像为不同的实体类型使用不同的 ORM)。
@Nazz IQueryable1-创建一个接口
interface IMain<T> where T : class
List<T> GetAll();
T GetById(int id);
void Add(T entity);
void Edit(T entity);
void Del(int id);
int Savechange();
2-创建一个类
public class Main<T> : IMain<T> where T : class
public DataContext db;
public void Add(T entity)
db.Set<T>().Add(entity);
public void Del(int id)
var q = GetById(id);
db.Set<T>().Remove(q);
public void Edit(T entity)
db.Entry<T>(entity).State = EntityState.Modified;
public List<T> GetAll()
return db.Set<T>().Select(a=>a).ToList();
public T GetById(int id)
return db.Set<T>().Find(id);
public int Savechange()
return db.SaveChanges();
3-创建一个名为 YourTable ForExample Student
的存储库 public class Student : Main<Tbl_Student>
public Student()
db = new DataContext();
4-为您的行动编写此代码
Student student=new Student();
student.Del(3);
int a = student.Savechange();
【讨论】:
【参考方案2】:您可以使用表达式关键字来做到这一点;
public interface IRepository<TEntity> where TEntity : Entity
IQueryable<TEntity> Query(Expression<Func<TEntity, bool>> predicate);
void Save(TEntity entity);
void Delete(TEntity entity);
public abstract class EfRepository<T> : IRepository<T> where T : Entity
private readonly DbContext _dbContext;
protected readonly DbSet<T> _dbSet;
public EfRepository(YourDbContextContext dbContext)
_dbContext = dbContext;
_dbSet = dbContext.Set<T>();
public void Delete(T entity)
if (entity == null) return;
else
DbEntityEntry dbEntityEntry = _dbContext.Entry(entity);
if (dbEntityEntry.State != EntityState.Deleted)
dbEntityEntry.State = EntityState.Deleted;
else
_dbSet.Attach(entity);
_dbSet.Remove(entity);
_dbContext.SaveChanges();
public IQueryable<T> Query(Expression<Func<T, bool>> predicate)
return _dbSet.Where(predicate);
public void Save(T entity)
if (entity.Id > 0)
_dbSet.Attach(entity);
_dbContext.Entry(entity).State = EntityState.Modified;
_dbContext.SaveChanges();
else
_dbSet.Add(entity);
_dbContext.SaveChanges();
public class Entity
public int Id get; set;
然后创建您的存储库;
public interface IUserRepository : IRepository<User>
//Also you can add here another methods according to your needs
public class UserRepository : EfRepository<User>,IUserRepository
public UserRepository(YourDbContext yourDbContext) : base(yourDbContext)
那就用吧;
IUserRepository _userRepository => Getit
//If there are entities according to your conditions, this will return them, then use it
_userRepository.Query(u => u.Id == userId);
【讨论】:
【参考方案3】:我曾经使用它,但正如许多开发人员所说,它会增加代码的复杂性并可能导致问题:
我的interface IRepositoryBase
的代码:
public interface IRepositoryBase<TEntity> where TEntity : class
void Add(TEntity objModel);
void AddRange(IEnumerable<TEntity> objModel);
TEntity GetId(int id);
Task<TEntity> GetIdAsync(int id);
TEntity Get(Expression<Func<TEntity, bool>> predicate);
Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> predicate);
IEnumerable<TEntity> GetList(Expression<Func<TEntity, bool>> predicate);
Task<IEnumerable<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> predicate);
IEnumerable<TEntity> GetAll();
Task<IEnumerable<TEntity>> GetAllAsync();
int Count();
Task<int> CountAsync();
void Update(TEntity objModel);
void Remove(TEntity objModel);
void Dispose();
我的interface
在repsoitory RepositoryBase
上的实现代码:
public class RepositoryBase<TEntity> : IRepositoryBase<TEntity> where TEntity : class
#region Fields
protected readonly EntityContext _context = new EntityContext();
#endregion
#region Methods
public void Add(TEntity objModel)
_context.Set<TEntity>().Add(objModel);
_context.SaveChanges();
public void AddRange(IEnumerable<TEntity> objModel)
_context.Set<TEntity>().AddRange(objModel);
_context.SaveChanges();
public TEntity GetId(int id)
return _context.Set<TEntity>().Find(id);
public async Task<TEntity> GetIdAsync(int id)
return await _context.Set<TEntity>().FindAsync(id);
public TEntity Get(Expression<Func<TEntity, bool>> predicate)
return _context.Set<TEntity>().FirstOrDefault(predicate);
public async Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> predicate)
return await _context.Set<TEntity>().FirstOrDefaultAsync(predicate);
public IEnumerable<TEntity> GetList(Expression<Func<TEntity, bool>> predicate)
return _context.Set<TEntity>().Where<TEntity>(predicate).ToList();
public async Task<IEnumerable<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> predicate)
return await Task.Run(() =>
_context.Set<TEntity>().Where<TEntity>(predicate));
public IEnumerable<TEntity> GetAll()
return _context.Set<TEntity>().ToList();
public async Task<IEnumerable<TEntity>> GetAllAsync()
return await Task.Run(() => _context.Set<TEntity>());
public int Count()
return _context.Set<TEntity>().Count();
public async Task<int> CountAsync()
return await _context.Set<TEntity>().CountAsync();
public void Update(TEntity objModel)
_context.Entry(objModel).State = EntityState.Modified;
_context.SaveChanges();
public void Remove(TEntity objModel)
_context.Set<TEntity>().Remove(objModel);
_context.SaveChanges();
public void Dispose()
_context.Dispose();
#endregion
我的实体interface
:
public interface IMyEntityRepository : IRepositoryBase<MyEntity>
//here you can place other implementations your repository doesn't have
public class MyEntityRepository : RepositoryBase<MyEntity>, IMyEntityRepository
如何调用(我用的是依赖注入):
public class MyServiceOrController
#region Fields
private readonly IMyEntityRepository _myEntityRepository;
#endregion
#region Constructors
public MyServiceOrController(IMyEntityRepository myEntityRepository)
_myEntityRepository = myEntityRepository;
#endregion
#region Methods
public IList<MyEntity> TestGetAll()
return _myEntityRepository.GetAll();
#endregion
【讨论】:
带有 ThenIncludes 的通用存储库模式
...一是我实现存储库模式的DataAccess层。我的主要关注点是EntityFramework仅在DataAccess层中被引用。我需要在查询中包含关系,因此我调整了查询方法以接收Includes作为输入。 查看详情
通用存储库、工作单元、Unity 的架构问题
...时间】:2019-01-0614:49:36【问题描述】:我正在使用MVC5、EntityFramework、Unity、UnitOfWork和GenericRepository开发我的项目架构之一,而且我还没有使用AutoMapper或任何其他类似于AutoMa 查看详情
访问存储库中的 UnitOfWork 是不好的设计吗?
...itory?【发布时间】:2013-05-0218:24:09【问题描述】:背景:Entityframework4.1和MVC4我的设置有模型实体,然后是通用存储库,然后是从通用存储库继承的UserRepository、ProductRepository等特定存储库的模型。 查看详情
java示例代码_Wrap Play/JPA';具有通用存储库的s模型类
java示例代码_Wrap Play/JPA';具有通用存储库的s模型类 查看详情
ASP.NET MVC,EntityFramework,DBContext,不同项目中的存储库[关闭]
】ASP.NETMVC,EntityFramework,DBContext,不同项目中的存储库[关闭]【英文标题】:ASP.NETMVC,EntityFramework,DBContext,RepositoryinadifferentProject[closed]【发布时间】:2013-11-0710:18:08【问题描述】:我目前正在开发一个ASP.NETMVC5项目,我正在尝试... 查看详情
具有实体框架 4.1 和父/子关系的存储库模式
】具有实体框架4.1和父/子关系的存储库模式【英文标题】:RepositoryPatternwithEntityFramework4.1andParent/ChildRelationships【发布时间】:2011-11-0212:23:45【问题描述】:我仍然对存储库模式有些困惑。我想使用此模式的主要原因是避免从域... 查看详情
在entityframework4中使用存储库/uow模式的多个objectcontexts(代码片段)
我在asp.netWeb应用程序中使用EF4和StructureMap。我正在使用工作模式的存储库/单元作为detailedinthispost。在代码中,有一行代表在Global.asax中委托ObjectContext的设置。EntityUnitOfWorkFactory.SetObjectContext(()=>newMyObjectContext());在网页代码隐藏... 查看详情
具有资源的通用静态库
】具有资源的通用静态库【英文标题】:Universalstaticlibrarywithresources【发布时间】:2013-12-1710:55:02【问题描述】:是否可以使用资源(如图像和xib文件)创建通用静态库。我创建了包含图像和xib文件的静态库,它运行良好。但我... 查看详情
每个实体的通用存储库还是特定存储库?
】每个实体的通用存储库还是特定存储库?【英文标题】:GenericRepositoryorSpecificRepositoryforeachentity?【发布时间】:2019-01-1704:16:24【问题描述】:背景在我工作的公司,我被要求更新旧的MVC应用程序并为SQL数据库实现存储库模式。... 查看详情
Entity Framework 6 异步操作和 TranscationScope
】EntityFramework6异步操作和TranscationScope【英文标题】:EntityFramework6asyncoperationsandTranscationScope【发布时间】:2015-03-2321:39:53【问题描述】:我在***上搜索但找不到类似的问题,如果已经有请指出。我试图实现一个具有同步和异步... 查看详情
csharpef的通用存储库(代码片段)
存储库模式和聚合根模式和实体框架
...体框架【英文标题】:RepositoryPatternandaggregaterootpatternandEntityFramework【发布时间】:2013-02-1016:06:27【问题描述】:我正在根据存储库模式、聚合根和工作单元来构建我的应用程序。我正在使用EntityFramework5作为ORM。我不知道如何继... 查看详情
没有 LINQ 扩展的 NHibernate 通用存储库?
】没有LINQ扩展的NHibernate通用存储库?【英文标题】:NHibernategenericrepositorywithoutLINQextension?【发布时间】:2013-11-0412:55:12【问题描述】:我正在寻找几天前的答案,但没有结果。我正在尝试使用NHibernate为通用存储库实现IRepository... 查看详情
csharp存储库模式的通用实现(代码片段)
Xamarin 项目中 SQLite-Net 的通用存储库
】Xamarin项目中SQLite-Net的通用存储库【英文标题】:GenericRepositoryforSQLite-NetinXamarinProject【发布时间】:2015-05-1700:10:48【问题描述】:我想知道是否有一种方法可以为我的Xamarin项目编写通用存储库,而不是为我的对象中的每个实... 查看详情
使用 EF 4.1 的通用存储库有啥意义
】使用EF4.1的通用存储库有啥意义【英文标题】:GenericRepositoryWithEF4.1whatisthepoint使用EF4.1的通用存储库有什么意义【发布时间】:2011-08-0307:15:12【问题描述】:当我深入研究DbContext、DbSet和相关接口时,我想知道为什么您需要围... 查看详情
Ninject + Bind 通用存储库
】Ninject+Bind通用存储库【英文标题】:Ninject+Bindgenericrepository【发布时间】:2011-05-2105:00:34【问题描述】:我正在尝试将通用IRepository接口绑定到我的通用存储库-但是它总是返回null?我尝试过各种方法,例如:Bind(typeof(IRepository&... 查看详情
EntityFramework 模型的通用 Getter
】EntityFramework模型的通用Getter【英文标题】:GenericGetterforEntityFrameworkmodels【发布时间】:2017-02-0100:29:53【问题描述】:使用EntityFrameworkv4,我想在C#中为我的模型类创建一个通用getter。我不知道这是否可能以及如何实现。我面临... 查看详情