zoukankan      html  css  js  c++  java
  • IOC+EF+Core项目搭建EF封装(一)

    添加应用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开源项目出抠出来的

  • 相关阅读:
    MyBatis框架(一)
    开始约定编程——Spring AOP
    Spring Boot快速入门
    全注解下的Spring IoC
    Java泛型
    Java异常
    windows监控web程序连接数
    winform导出excel报'object' does not contain a definition for 'get_Range'的问题
    git基本操作
    .net core中使用HttpClient碰到的问题:This instance has already started one or more requests. Properties can only be modified before sending the first request
  • 原文地址:https://www.cnblogs.com/shuaimeng/p/11338620.html
Copyright © 2011-2022 走看看