添加應用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開源項目出摳出來的