添加应用Microsoft.EntityFrameworkCore;Microsoft.EntityFrameworkCore.Design;Microsoft.EntityFrameworkCore.SqlServer
base类
public abstract partial class BaseEntity { /// <summary> /// id /// </summary> public Guid gid { get; set; } }
分装仓储结构接口
/// <summary> /// 仓储db接口 /// </summary> public partial interface IDbContext { #region 方法 /// <summary> /// 创建可用于查询和保存实体实例的DbSet /// </summary> /// <typeparam name="TEntity">Entity type</typeparam> /// <returns>A set for the given entity type</returns> DbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity; /// <summary> /// 将在此上下文中所做的所有更改保存到数据库 /// </summary> /// <returns>The number of state entries written to the database</returns> int SaveChanges(); /// <summary> /// 生成一个脚本,为当前模型创建所有表 /// </summary> /// <returns>A SQL script</returns> string GenerateCreateScript(); /// <summary> /// 基于原始SQL查询为查询类型创建LINQ查询 /// </summary> /// <typeparam name="TQuery">Query type</typeparam> /// <param name="sql">The raw SQL query</param> /// <returns>An IQueryable representing the raw SQL query</returns> IQueryable<TQuery> QueryFromSql<TQuery>(string sql) where TQuery : class; /// <summary> /// 基于原始SQL查询为实体创建LINQ查询 /// </summary> /// <typeparam name="TEntity">Entity type</typeparam> /// <param name="sql">The raw SQL query</param> /// <param name="parameters">The values to be assigned to parameters</param> /// <returns>An IQueryable representing the raw SQL query</returns> IQueryable<TEntity> EntityFromSql<TEntity>(string sql, params object[] parameters) where TEntity : BaseEntity; /// <summary> /// 对数据库执行给定的SQL /// </summary> /// <param name="sql">The SQL to execute</param> /// <param name="doNotEnsureTransaction">true - the transaction creation is not ensured; false - the transaction creation is ensured.</param> /// <param name="timeout">The timeout to use for command. Note that the command timeout is distinct from the connection timeout, which is commonly set on the database connection string</param> /// <param name="parameters">Parameters to use with the SQL</param> /// <returns>The number of rows affected</returns> int ExecuteSqlCommand(RawSqlString sql, bool doNotEnsureTransaction = false, int? timeout = null, params object[] parameters); /// <summary> /// 从上下文中分离一个实体 /// </summary> /// <typeparam name="TEntity">Entity type</typeparam> /// <param name="entity">Entity</param> void Detach<TEntity>(TEntity entity) where TEntity : BaseEntity; #endregion }
/// <summary> /// 基础仓储接口 /// </summary> public partial interface IRepository<TEntity> where TEntity : BaseEntity { #region 方法 /// <summary> /// 查询对象 /// </summary> TEntity GetById(object gid); /// <summary> /// 添加 /// </summary> void Insert(TEntity entity); /// <summary> /// 批量添加 /// </summary> void Insert(IEnumerable<TEntity> entities); /// <summary> /// 修改 /// </summary> void Update(TEntity entity); /// <summary> /// 批量修改 /// </summary> void Update(IEnumerable<TEntity> entities); /// <summary> /// 删除 /// </summary> void Delete(TEntity entity); /// <summary> /// 批量删除 /// </summary> void Delete(IEnumerable<TEntity> entities); #endregion #region 属性 /// <summary> /// 查询数据集 /// </summary> IQueryable<TEntity> Table { get; } /// <summary> /// 获取一个启用“no tracking”(EF特性)的表,仅当您仅为只读操作加载记录时才使用它 /// </summary> IQueryable<TEntity> TableNoTracking { get; } #endregion }
/// <summary> /// 基础仓储实现 /// </summary> public partial class EfRepository<TEntity> : IRepository<TEntity> where TEntity : BaseEntity { #region 参数 private readonly IDbContext _context; private DbSet<TEntity> _entities; #endregion #region 构造函数 public EfRepository(IDbContext context) { this._context = context; } #endregion #region 公共方法 /// <summary> /// 实体更改的回滚并返回完整的错误消息 /// </summary> /// <param name="exception">Exception</param> /// <returns>Error message</returns> protected string GetFullErrorTextAndRollbackEntityChanges(DbUpdateException exception) { //回滚实体 if (_context is DbContext dbContext) { var entries = dbContext.ChangeTracker.Entries() .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified).ToList(); entries.ForEach(entry => entry.State = EntityState.Unchanged); } _context.SaveChanges(); return exception.ToString(); } #endregion #region 方法 /// <summary> /// 按id获取实体 /// </summary> /// <param name="id">Identifier</param> /// <returns>Entity</returns> public virtual TEntity GetById(object id) { return Entities.Find(id); } /// <summary> /// 添加 /// </summary> /// <param name="entity">Entity</param> public virtual void Insert(TEntity entity) { if (entity == null) throw new ArgumentNullException(nameof(entity)); try { Entities.Add(entity); _context.SaveChanges(); } catch (DbUpdateException exception) { //ensure that the detailed error text is saved in the Log throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception); } } /// <summary> /// 批量添加 /// </summary> /// <param name="entities">Entities</param> public virtual void Insert(IEnumerable<TEntity> entities) { if (entities == null) throw new ArgumentNullException(nameof(entities)); try { Entities.AddRange(entities); _context.SaveChanges(); } catch (DbUpdateException exception) { //ensure that the detailed error text is saved in the Log throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception); } } /// <summary> /// 修改 /// </summary> /// <param name="entity">Entity</param> public virtual void Update(TEntity entity) { if (entity == null) throw new ArgumentNullException(nameof(entity)); try { Entities.Update(entity); _context.SaveChanges(); } catch (DbUpdateException exception) { //ensure that the detailed error text is saved in the Log throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception); } } /// <summary> /// 批量修改 /// </summary> /// <param name="entities">Entities</param> public virtual void Update(IEnumerable<TEntity> entities) { if (entities == null) throw new ArgumentNullException(nameof(entities)); try { Entities.UpdateRange(entities); _context.SaveChanges(); } catch (DbUpdateException exception) { //ensure that the detailed error text is saved in the Log throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception); } } /// <summary> /// 删除 /// </summary> /// <param name="entity">Entity</param> public virtual void Delete(TEntity entity) { if (entity == null) throw new ArgumentNullException(nameof(entity)); try { Entities.Remove(entity); _context.SaveChanges(); } catch (DbUpdateException exception) { //ensure that the detailed error text is saved in the Log throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception); } } /// <summary> /// 批量删除 /// </summary> /// <param name="entities">Entities</param> public virtual void Delete(IEnumerable<TEntity> entities) { if (entities == null) throw new ArgumentNullException(nameof(entities)); try { Entities.RemoveRange(entities); _context.SaveChanges(); } catch (DbUpdateException exception) { //ensure that the detailed error text is saved in the Log throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception); } } #endregion #region 属性 /// <summary> /// 获取表 /// </summary> public virtual IQueryable<TEntity> Table => Entities; /// <summary> /// 获取一个启用“no tracking”(EF特性)的表,仅当您仅为只读操作加载记录时才使用它 /// </summary> public virtual IQueryable<TEntity> TableNoTracking => Entities.AsNoTracking(); /// <summary> /// 获取设置模板 /// </summary> protected virtual DbSet<TEntity> Entities { get { if (_entities == null) _entities = _context.Set<TEntity>(); return _entities; } } #endregion }
ef的模型映射封装
/// <summary> /// 表示数据库上下文模型映射配置 /// </summary> public partial interface IMappingConfiguration { /// <summary> /// 应用此映射配置 /// </summary> /// <param name="modelBuilder">用于构造数据库上下文模型的生成器</param> void ApplyConfiguration(ModelBuilder modelBuilder); }
/// <summary> /// 表示基本实体映射配置 /// </summary> /// <typeparam name="TEntity">Entity type</typeparam> public partial class NopEntityTypeConfiguration<TEntity> : IMappingConfiguration, IEntityTypeConfiguration<TEntity> where TEntity : BaseEntity { #region Utilities /// <summary> /// Developers can override this method in custom partial classes in order to add some custom configuration code /// </summary> /// <param name="builder">The builder to be used to configure the entity</param> protected virtual void PostConfigure(EntityTypeBuilder<TEntity> builder) { } #endregion #region Methods /// <summary> /// Configures the entity /// </summary> /// <param name="builder">The builder to be used to configure the entity</param> public virtual void Configure(EntityTypeBuilder<TEntity> builder) { //add custom configuration this.PostConfigure(builder); } /// <summary> /// Apply this mapping configuration /// </summary> /// <param name="modelBuilder">The builder being used to construct the model for the database context</param> public virtual void ApplyConfiguration(ModelBuilder modelBuilder) { modelBuilder.ApplyConfiguration(this); } #endregion }
/// <summary> /// 表示基本EF对象上下文 /// </summary> public partial class NopObjectContext : DbContext, IDbContext { #region 构造函数 public NopObjectContext(DbContextOptions<NopObjectContext> options) : base(options) { } #endregion #region 公共方法 /// <summary> /// 进一步配置注册映射模型 /// </summary> /// <param name="modelBuilder">用于为该上下文构造模型的构造器</param> protected override void OnModelCreating(ModelBuilder modelBuilder) { //动态加载所有实体和查询类型配置 var typeConfigurations = Assembly.GetExecutingAssembly().GetTypes().Where(type => (type.BaseType?.IsGenericType ?? false) && (type.BaseType.GetGenericTypeDefinition() == typeof(NopEntityTypeConfiguration<>))); foreach (var typeConfiguration in typeConfigurations) { var configuration = (IMappingConfiguration)Activator.CreateInstance(typeConfiguration); configuration.ApplyConfiguration(modelBuilder); } base.OnModelCreating(modelBuilder); } /// <summary> /// 通过添加传递的参数来修改输入SQL查询 /// </summary> /// <param name="sql">The raw SQL query</param> /// <param name="parameters">The values to be assigned to parameters</param> /// <returns>Modified raw SQL query</returns> protected virtual string CreateSqlWithParameters(string sql, params object[] parameters) { //add parameters to sql for (var i = 0; i <= (parameters?.Length ?? 0) - 1; i++) { if (!(parameters[i] is DbParameter parameter)) continue; sql = $"{sql}{(i > 0 ? "," : string.Empty)} @{parameter.ParameterName}"; //whether parameter is output if (parameter.Direction == ParameterDirection.InputOutput || parameter.Direction == ParameterDirection.Output) sql = $"{sql} output"; } return sql; } #endregion #region 方法 /// <summary> /// 创建可用于查询和保存实体实例的DbSet /// </summary> /// <typeparam name="TEntity">Entity type</typeparam> /// <returns>A set for the given entity type</returns> public virtual new DbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity { return base.Set<TEntity>(); } /// <summary> /// 生成一个脚本,为当前模型创建所有表 /// </summary> /// <returns>A SQL script</returns> public virtual string GenerateCreateScript() { return this.Database.GenerateCreateScript(); } /// <summary> /// 基于原始SQL查询为查询类型创建LINQ查询 /// </summary> /// <typeparam name="TQuery">Query type</typeparam> /// <param name="sql">The raw SQL query</param> /// <returns>An IQueryable representing the raw SQL query</returns> public virtual IQueryable<TQuery> QueryFromSql<TQuery>(string sql) where TQuery : class { return this.Query<TQuery>().FromSql(sql); } /// <summary> ///基于原始SQL查询为实体创建LINQ查询 /// </summary> /// <typeparam name="TEntity">Entity type</typeparam> /// <param name="sql">The raw SQL query</param> /// <param name="parameters">The values to be assigned to parameters</param> /// <returns>An IQueryable representing the raw SQL query</returns> public virtual IQueryable<TEntity> EntityFromSql<TEntity>(string sql, params object[] parameters) where TEntity : BaseEntity { return this.Set<TEntity>().FromSql(CreateSqlWithParameters(sql, parameters), parameters); } /// <summary> /// 对数据库执行给定的SQL /// </summary> /// <param name="sql">The SQL to execute</param> /// <param name="doNotEnsureTransaction">true - the transaction creation is not ensured; false - the transaction creation is ensured.</param> /// <param name="timeout">The timeout to use for command. Note that the command timeout is distinct from the connection timeout, which is commonly set on the database connection string</param> /// <param name="parameters">Parameters to use with the SQL</param> /// <returns>The number of rows affected</returns> public virtual int ExecuteSqlCommand(RawSqlString sql, bool doNotEnsureTransaction = false, int? timeout = null, params object[] parameters) { //set specific command timeout var previousTimeout = this.Database.GetCommandTimeout(); this.Database.SetCommandTimeout(timeout); var result = 0; if (!doNotEnsureTransaction) { //use with transaction using (var transaction = this.Database.BeginTransaction()) { result = this.Database.ExecuteSqlCommand(sql, parameters); transaction.Commit(); } } else result = this.Database.ExecuteSqlCommand(sql, parameters); //return previous timeout back this.Database.SetCommandTimeout(previousTimeout); return result; } /// <summary> /// 从上下文中分离一个实体 /// </summary> /// <typeparam name="TEntity">Entity type</typeparam> /// <param name="entity">Entity</param> public virtual void Detach<TEntity>(TEntity entity) where TEntity : BaseEntity { if (entity == null) throw new ArgumentNullException(nameof(entity)); var entityEntry = this.Entry(entity); if (entityEntry == null) return; //set the entity is not being tracked by the context entityEntry.State = EntityState.Detached; } #endregion }
代码都是从nop开源项目出抠出来的