欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

NetCore3.1webApi + EFCore + DI 框架封装

程序员文章站 2022-04-25 20:03:47
框架结构 实体层: Typecho.Enties 仓储层: Typecho.IRepository IconcardContext.cs IRepositoryFactory.cs IRepositorys.cs Typecho.Repository RepositoryFactory.cs Rep ......

框架结构

实体层:

typecho.enties

仓储层:

typecho.irepository

iconcardcontext.cs

irepositoryfactory.cs

irepositorys.cs

typecho.repository

repositoryfactory.cs

repositorys.cs

typechocontext.cs

业务层:

typecho.iservice

ibaseservice.cs

itypechotestservice.cs

typecho.service

baseservice.cs

typechoservice.cs

ui层(api):

typechocore1

testcontroller.cs

一: ef从数据库生成实体类到enties

1.执行以下语句安装依赖包

install-package mysql.data.entityframeworkcore -pre
install-package pomelo.entityframeworkcore.mysql
install-package microsoft.entityframeworkcore.tools
install-package microsoft.visualstudio.web.codegeneration.design

2.在程序包包管理器控制台

scaffold-dbcontext "server=localhost;userid=root;pwd=1;port=3306;database=syerp;sslmode=none;" pomelo.entityframeworkcore.mysql -outputdir models -force

自动生成所有类模型文件,typechocontext.cs数据库上下文自动创建好了

-outputdir  实体文件所存放的文件目录
-contextdir   dbcontext文件存放的目录
-context         dbcontext文件名
-schemas       需要生成实体数据的数据表所在的模式
-tables            需要生成实体数据的数据表的集合
-dataannotations
-usedatabasenames   直接使用数据库中的表名和列名(某些版本不支持)
-force              强制执行,重写已经存在的实体文件

链接: asp.net core3.1 实战开发(ef+mysql 从数据库生成实体类到项目)

二:封装数据访问层

封装仓储repositorys模式,把typechocontext.cs这个类复制到typecho.repository程序集中

typechocontext类:

using microsoft.entityframeworkcore;
using typecho.enties.models;
using typecho.irepository;

namespace typecho.repository
{
    public partial class typechocontext : dbcontext , iconcardcontext
    {
      

        public typechocontext(dbcontextoptions<typechocontext> options)
            : base(options)
        {
        }

        public virtual dbset<typecho_comments> typecho_comments { get; set; }
        public virtual dbset<typecho_contents> typecho_contents { get; set; }
        public virtual dbset<typecho_fields> typecho_fields { get; set; }
        public virtual dbset<typecho_links> typecho_links { get; set; }
        public virtual dbset<typecho_metas> typecho_metas { get; set; }
        public virtual dbset<typecho_options> typecho_options { get; set; }
        public virtual dbset<typecho_relationships> typecho_relationships { get; set; }
        public virtual dbset<typecho_users> typecho_users { get; set; }

          public virtual dbset<typecho_test> typecho_test { get; set; }

//        protected override void onconfiguring(dbcontextoptionsbuilder optionsbuilder)
//        {
//            if (!optionsbuilder.isconfigured)
//            {
//#warning to protect potentially sensitive information in your connection string, you should move it out of source code. see http://go.microsoft.com/fwlink/?linkid=723263 for guidance on storing connection strings.
//                optionsbuilder.usemysql("server=localhost;userid=root;pwd=woshishui;port=3306;database=typecho;sslmode=none", x => x.serverversion("8.0.16-mysql"));
//            }
//        }

        protected override void onmodelcreating(modelbuilder modelbuilder)
        {
            modelbuilder.entity<typecho_comments>(entity =>
            {
                entity.haskey(e => e.coid)
                    .hasname("primary");

                entity.hasindex(e => e.cid)
                    .hasname("cid");

                entity.hasindex(e => e.created)
                    .hasname("created");

                entity.property(e => e.coid).hascolumntype("int(10) unsigned");

                entity.property(e => e.agent)
                    .hascolumntype("varchar(200)")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.author)
                    .hascolumntype("varchar(200)")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.authorid)
                    .hascolumntype("int(10) unsigned")
                    .hasdefaultvaluesql("'0'");

                entity.property(e => e.cid)
                    .hascolumntype("int(10) unsigned")
                    .hasdefaultvaluesql("'0'");

                entity.property(e => e.created)
                    .hascolumntype("int(10) unsigned")
                    .hasdefaultvaluesql("'0'");

                entity.property(e => e.ip)
                    .hascolumntype("varchar(64)")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.mail)
                    .hascolumntype("varchar(200)")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.ownerid)
                    .hascolumntype("int(10) unsigned")
                    .hasdefaultvaluesql("'0'");

                entity.property(e => e.parent)
                    .hascolumntype("int(10) unsigned")
                    .hasdefaultvaluesql("'0'");

                entity.property(e => e.stars)
                    .hascolumntype("int(10)")
                    .hasdefaultvaluesql("'0'");

                entity.property(e => e.status)
                    .hascolumntype("varchar(16)")
                    .hasdefaultvaluesql("'approved'")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.text)
                    .hascolumntype("text")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.type)
                    .hascolumntype("varchar(16)")
                    .hasdefaultvaluesql("'comment'")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.url)
                    .hascolumntype("varchar(200)")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");
            });

            modelbuilder.entity<typecho_contents>(entity =>
            {
                entity.haskey(e => e.cid)
                    .hasname("primary");

                entity.hasindex(e => e.created)
                    .hasname("created");

                entity.hasindex(e => e.slug)
                    .hasname("slug")
                    .isunique();

                entity.property(e => e.cid).hascolumntype("int(10) unsigned");

                entity.property(e => e.allowcomment)
                    .hascolumntype("char(1)")
                    .hasdefaultvaluesql("'0'")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.allowfeed)
                    .hascolumntype("char(1)")
                    .hasdefaultvaluesql("'0'")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.allowping)
                    .hascolumntype("char(1)")
                    .hasdefaultvaluesql("'0'")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.authorid)
                    .hascolumntype("int(10) unsigned")
                    .hasdefaultvaluesql("'0'");

                entity.property(e => e.commentsnum)
                    .hascolumntype("int(10) unsigned")
                    .hasdefaultvaluesql("'0'");

                entity.property(e => e.created)
                    .hascolumntype("int(10) unsigned")
                    .hasdefaultvaluesql("'0'");

                entity.property(e => e.modified)
                    .hascolumntype("int(10) unsigned")
                    .hasdefaultvaluesql("'0'");

                entity.property(e => e.order)
                    .hascolumntype("int(10) unsigned")
                    .hasdefaultvaluesql("'0'");

                entity.property(e => e.parent)
                    .hascolumntype("int(10) unsigned")
                    .hasdefaultvaluesql("'0'");

                entity.property(e => e.password)
                    .hascolumntype("varchar(32)")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.slug)
                    .hascolumntype("varchar(200)")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.status)
                    .hascolumntype("varchar(16)")
                    .hasdefaultvaluesql("'publish'")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.template)
                    .hascolumntype("varchar(32)")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.text)
                    .hascolumntype("longtext")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.title)
                    .hascolumntype("varchar(200)")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.type)
                    .hascolumntype("varchar(16)")
                    .hasdefaultvaluesql("'post'")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.views)
                    .hascolumntype("int(10)")
                    .hasdefaultvaluesql("'0'");
            });

            modelbuilder.entity<typecho_fields>(entity =>
            {
                entity.haskey(e => new { e.cid, e.name })
                    .hasname("primary");

                entity.hasindex(e => e.float_value)
                    .hasname("float_value");

                entity.hasindex(e => e.int_value)
                    .hasname("int_value");

                entity.property(e => e.cid).hascolumntype("int(10) unsigned");

                entity.property(e => e.name)
                    .hascolumntype("varchar(200)")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.float_value).hasdefaultvaluesql("'0'");

                entity.property(e => e.int_value)
                    .hascolumntype("int(10)")
                    .hasdefaultvaluesql("'0'");

                entity.property(e => e.str_value)
                    .hascolumntype("text")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.type)
                    .hascolumntype("varchar(8)")
                    .hasdefaultvaluesql("'str'")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");
            });

            modelbuilder.entity<typecho_links>(entity =>
            {
                entity.haskey(e => e.lid)
                    .hasname("primary");

                entity.property(e => e.lid)
                    .hascolumntype("int(10) unsigned")
                    .hascomment("links表主键");

                entity.property(e => e.description)
                    .hascolumntype("varchar(200)")
                    .hascomment("links描述")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.image)
                    .hascolumntype("varchar(200)")
                    .hascomment("links图片")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.name)
                    .hascolumntype("varchar(200)")
                    .hascomment("links名称")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.order)
                    .hascolumntype("int(10) unsigned")
                    .hasdefaultvaluesql("'0'")
                    .hascomment("links排序");

                entity.property(e => e.sort)
                    .hascolumntype("varchar(200)")
                    .hascomment("links分类")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.url)
                    .hascolumntype("varchar(200)")
                    .hascomment("links网址")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.user)
                    .hascolumntype("varchar(200)")
                    .hascomment("自定义")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");
            });

            modelbuilder.entity<typecho_metas>(entity =>
            {
                entity.haskey(e => e.mid)
                    .hasname("primary");

                entity.hasindex(e => e.slug)
                    .hasname("slug");

                entity.property(e => e.mid).hascolumntype("int(10) unsigned");

                entity.property(e => e.count)
                    .hascolumntype("int(10) unsigned")
                    .hasdefaultvaluesql("'0'");

                entity.property(e => e.description)
                    .hascolumntype("varchar(200)")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.name)
                    .hascolumntype("varchar(200)")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.order)
                    .hascolumntype("int(10) unsigned")
                    .hasdefaultvaluesql("'0'");

                entity.property(e => e.parent)
                    .hascolumntype("int(10) unsigned")
                    .hasdefaultvaluesql("'0'");

                entity.property(e => e.slug)
                    .hascolumntype("varchar(200)")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.type)
                    .isrequired()
                    .hascolumntype("varchar(32)")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");
            });

            modelbuilder.entity<typecho_options>(entity =>
            {
                entity.haskey(e => new { e.name, e.user })
                    .hasname("primary");

                entity.property(e => e.name)
                    .hascolumntype("varchar(32)")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.user).hascolumntype("int(10) unsigned");

                entity.property(e => e.value)
                    .hascolumntype("text")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");
            });

            modelbuilder.entity<typecho_relationships>(entity =>
            {
                entity.haskey(e => new { e.cid, e.mid })
                    .hasname("primary");

                entity.property(e => e.cid).hascolumntype("int(10) unsigned");

                entity.property(e => e.mid).hascolumntype("int(10) unsigned");
            });

            modelbuilder.entity<typecho_users>(entity =>
            {
                entity.haskey(e => e.uid)
                    .hasname("primary");

                entity.hasindex(e => e.mail)
                    .hasname("mail")
                    .isunique();

                entity.hasindex(e => e.name)
                    .hasname("name")
                    .isunique();

                entity.property(e => e.uid).hascolumntype("int(10) unsigned");

                entity.property(e => e.activated)
                    .hascolumntype("int(10) unsigned")
                    .hasdefaultvaluesql("'0'");

                entity.property(e => e.authcode)
                    .hascolumntype("varchar(64)")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.created)
                    .hascolumntype("int(10) unsigned")
                    .hasdefaultvaluesql("'0'");

                entity.property(e => e.group)
                    .hascolumntype("varchar(16)")
                    .hasdefaultvaluesql("'visitor'")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.logged)
                    .hascolumntype("int(10) unsigned")
                    .hasdefaultvaluesql("'0'");

                entity.property(e => e.mail)
                    .hascolumntype("varchar(200)")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.name)
                    .hascolumntype("varchar(32)")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.password)
                    .hascolumntype("varchar(64)")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.screenname)
                    .hascolumntype("varchar(32)")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");

                entity.property(e => e.url)
                    .hascolumntype("varchar(200)")
                    .hascharset("utf8")
                    .hascollation("utf8_general_ci");
            });

            onmodelcreatingpartial(modelbuilder);
        }

        partial void onmodelcreatingpartial(modelbuilder modelbuilder);
    }
}

irepositorys接口:

 public interface irepositorys<t> : idisposable where t : class
    {
        /// <summary>
        /// 显式开启数据上下文事务
        /// </summary>
        /// <param name="isolationlevel">指定连接的事务锁定行为</param>
        void begintransaction(isolationlevel isolationlevel = isolationlevel.unspecified);

        /// <summary>
        /// 提交事务的更改
        /// </summary>
        void commit();

        /// <summary>
        /// 显式回滚事务,仅在显式开启事务后有用
        /// </summary>
        void rollback();

        /// <summary>
        /// 提交当前单元操作的更改
        /// </summary>
        int savechanges();
         task<int> savechangesasync();

        /// <summary>
        /// 获取 当前实体类型的查询数据集,数据将使用不跟踪变化的方式来查询,当数据用于展现时,推荐使用此数据集,如果用于新增,更新,删除时,请使用<see cref="trackentities"/>数据集
        /// </summary>
        iqueryable<t> entities { get; }

        /// <summary>
        /// 获取 当前实体类型的查询数据集,当数据用于新增,更新,删除时,使用此数据集,如果数据用于展现,推荐使用<see cref="entities"/>数据集
        /// </summary>
        iqueryable<t> trackentities { get; }

        /// <summary>
        /// 插入 - 通过实体对象添加
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <param name="issave">是否执行</param>
        /// /// <returns></returns>
        t add(t entity, bool issave = true);
         task<t> aysadd(t entity, bool issave = true);
        /// <summary>
        /// 批量插入 - 通过实体对象集合添加
        /// </summary>
        /// <param name="entitys">实体对象集合</param>
        /// <param name="issave">是否执行</param>
        void addrange(ienumerable<t> entitys, bool issave = true);

        /// <summary>
        /// 删除 - 通过实体对象删除
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <param name="issave">是否执行</param>
        void delete(t entity, bool issave = true);

        /// <summary>
        /// 批量删除 - 通过实体对象集合删除
        /// </summary>
        /// <param name="entitys">实体对象集合</param>
        /// <param name="issave">是否执行</param>
        void delete(bool issave = false, params t[] entitys);

        /// <summary>
        /// 删除 - 通过主键id删除
        /// </summary>
        /// <param name="id">主键id</param>
        task<int> asydelete(object id);
        int delete(object id);
        /// <summary>
        /// 批量删除 - 通过条件删除
        /// </summary>
        /// <param name="where">过滤条件</param>
        /// <param name="issave">是否执行</param>
        void delete(expression<func<t, bool>> @where, bool issave = true);

        /// <summary>
        /// 修改 - 通过实体对象修改
        /// </summary>
        /// <param name="entity">实体对象</param>
        task<int> aysupdate(t entity);

        int  update(t entity);
        /// <summary>
        /// 批量修改 - 通过实体对象集合修改
        /// </summary>
        /// <param name="entitys">实体对象集合</param>
        void update( params t[] entitys);

        /// <summary>
        /// 是否满足条件
        /// </summary>
        /// <param name="where">过滤条件</param>
        /// <returns></returns>
        bool any(expression<func<t, bool>> @where);

        /// <summary>
        /// 返回总条数
        /// </summary>
        /// <returns></returns>
        int count();

        /// <summary>
        /// 返回总条数 - 通过条件过滤
        /// </summary>
        /// <param name="where">过滤条件</param>
        /// <returns></returns>
        int count(expression<func<t, bool>> @where);

        /// <summary>
        /// 返回第一条记录
        /// </summary>
        /// <param name="where">过滤条件</param>
        /// <returns></returns>
        t firstordefault(expression<func<t, bool>> @where);

        /// <summary>
        /// 返回第一条记录 - 通过条件过滤
        /// </summary>
        /// <typeparam name="torder">排序约束</typeparam>
        /// <param name="where">过滤条件</param>
        /// <param name="order">排序条件</param>
        /// <param name="isdesc">排序方式</param>
        /// <returns></returns>
        t firstordefault<torder>(expression<func<t, bool>> @where, expression<func<t, torder>> order, bool isdesc = false);

        /// <summary>
        /// 去重查询
        /// </summary>
        /// <param name="where">过滤条件</param>
        /// <returns></returns>
        iqueryable<t> distinct(expression<func<t, bool>> @where);

        /// <summary>
        /// 条件查询
        /// </summary>
        /// <param name="where">过滤条件</param>
        /// <returns></returns>
        iqueryable<t> where(expression<func<t, bool>> @where);

        /// <summary>
        /// 条件查询 - 支持排序
        /// </summary>
        /// <typeparam name="torder">排序约束</typeparam>
        /// <param name="where">过滤条件</param>
        /// <param name="order">排序条件</param>
        /// <param name="isdesc">排序方式</param>
        /// <returns></returns>
        iqueryable<t> where<torder>(expression<func<t, bool>> @where, expression<func<t, torder>> order, bool isdesc = false);

        /// <summary>
        /// 条件分页查询 - 支持排序
        /// </summary>
        /// <typeparam name="torder">排序约束</typeparam>
        /// <param name="where">过滤条件</param>
        /// <param name="order">排序条件</param>
        /// <param name="pageindex">当前页码</param>
        /// <param name="pagesize">每页记录条数</param>
        /// <param name="count">返回总条数</param>
        /// <param name="isdesc">是否倒序</param>
        /// <returns></returns>
        ienumerable<t> where<torder>(func<t, bool> @where, func<t, torder> order, int pageindex, int pagesize, out int count, bool isdesc = false);

        /// <summary>
        /// 条件分页查询 - 支持排序 - 支持select导航属性查询
        /// </summary>
        /// <typeparam name="torder">排序约束</typeparam>
        /// <param name="where">过滤条件</param>
        /// <param name="order">排序条件</param>
        /// <param name="pageindex">当前页码</param>
        /// <param name="pagesize">每页记录条数</param>
        /// <param name="count">返回总条数</param>
        /// <param name="isdesc">是否倒序</param>
        /// <returns></returns>
        iqueryable<t> where<torder>(expression<func<t, bool>> @where, expression<func<t, torder>> order, int pageindex, int pagesize, out int count, bool isdesc = false);

        /// <summary>
        /// 获取所有数据
        /// </summary>
        /// <returns></returns>
        iqueryable<t> getall();

        /// <summary>
        /// 获取所有数据 - 支持排序
        /// </summary>
        /// <typeparam name="torder">排序约束</typeparam>
        /// <param name="order">排序条件</param>
        /// <param name="isdesc">排序方式</param>
        /// <returns></returns>
        iqueryable<t> getall<torder>(expression<func<t, torder>> order, bool isdesc = false);

        /// <summary>
        /// 根据id查询
        /// </summary>
        /// <typeparam name="ttype">字段类型</typeparam>
        /// <param name="id">主键id</param>
        /// <returns></returns>
        t getbyid<ttype>(ttype id);

        /// <summary>
        /// 获取最大值
        /// </summary>
        /// <typeparam name="ttype">字段类型</typeparam>
        /// <param name="column">字段条件</param>
        /// <returns></returns>
        ttype max<ttype>(expression<func<t, ttype>> column);

        /// <summary>
        /// 获取最大值
        /// </summary>
        /// <typeparam name="ttype">字段类型</typeparam>
        /// <param name="column">字段条件</param>
        /// <param name="where">过滤条件</param>
        /// <returns></returns>
        ttype max<ttype>(expression<func<t, ttype>> column, expression<func<t, bool>> @where);

        /// <summary>
        /// 获取最小值
        /// </summary>
        /// <typeparam name="ttype">字段类型</typeparam>
        /// <param name="column">字段条件</param>
        /// <returns></returns>
        ttype min<ttype>(expression<func<t, ttype>> column);

        /// <summary>
        /// 获取最小值
        /// </summary>
        /// <typeparam name="ttype">字段类型</typeparam>
        /// <param name="column">字段条件</param>
        /// <param name="where">过滤条件</param>
        /// <returns></returns>
        ttype min<ttype>(expression<func<t, ttype>> column, expression<func<t, bool>> @where);

        /// <summary>
        /// 获取总数
        /// </summary>
        /// <typeparam name="ttype">字段类型</typeparam>
        /// <param name="selector">字段条件</param>
        /// <param name="where">过滤条件</param>
        /// <returns></returns>
        ttype sum<ttype>(expression<func<t, ttype>> selector, expression<func<t, bool>> @where) where ttype : new();
    }

repositorys类,crud功能的封装

  public class repositorys<t> : irepositorys<t> where t : class
    {
        private typechocontext _dbcontext;
        private readonly dbset<t> _dbset;
        private readonly string _connstr;

        public repositorys(iconcardcontext mydbcontext)
        {
            _dbcontext = mydbcontext as typechocontext;
            if (_dbcontext == null)
            {
                return;
            }

            _dbset = _dbcontext.set<t>();
            _connstr = _dbcontext.database.getdbconnection().connectionstring;
        }

        public void begintransaction(isolationlevel isolationlevel = isolationlevel.unspecified)
        {
            if (_dbcontext.database.currenttransaction == null)
            {
                _dbcontext.database.begintransaction(isolationlevel);
            }
        }

        public void commit()
        {
            var transaction = this._dbcontext.database.currenttransaction;
            if (transaction != null)
            {
                try
                {
                    transaction.commit();
                }
                catch (exception)
                {
                    transaction.rollback();
                    throw;
                }
            }
        }

        public void rollback()
        {
            if (_dbcontext.database.currenttransaction != null)
            {
                _dbcontext.database.currenttransaction.rollback();
            }
        }

        public int savechanges()
        {
            return _dbcontext.savechanges();
        }
          public async task<int> savechangesasync()
        {
            return await _dbcontext.savechangesasync();
        }


        public iqueryable<t> entities
        {
            get { return _dbset.asnotracking(); }
        }

        public iqueryable<t> trackentities
        {
            get { return _dbset; }
        }

        public t add(t entity, bool issave = true)
        {

            _dbset.add(entity);
            if (issave)
            {
                savechanges();
            }
            return entity;
        }

         public async task<t> aysadd(t entity, bool issave = true)
        {
           await _dbset.addasync(entity);
            if (issave)
            {
               await  savechangesasync();
            }
            return entity;
        }

        public void addrange(ienumerable<t> entitys, bool issave = true)
        {
            _dbset.addrange(entitys);
            if (issave)
            {
                savechanges();
            }
        }

        public void delete(t entity, bool issave = true)
        {
            this._dbset.remove(entity);
            if (issave)
            {
                this.savechanges();
            }
        }

        public void delete(bool issave = true, params t[] entitys)
        {
            this._dbset.removerange(entitys);
            if (issave)
            {
                this.savechanges();
            }
        }

        public async task<int> asydelete(object id)
        {
             int de = 0;
             //执行查询
             var todoitem = await _dbset.findasync(id);
            if (todoitem == null)
            {
                //return notfound();
                de = 0;
            }
            else
            {
              _dbset.remove(todoitem);
             de = savechanges();
            }
            return de;
        }

           public int delete(object id)
        {
             int de = 0;
             //执行查询
             var todoitem =_dbset.find(id);
            if (todoitem == null)
            {
                //return notfound();
                de = 0;
            }
            else
            {
              _dbset.remove(todoitem);
             de = savechanges();
            }
            return de;
        }

        public void delete(expression<func<t, bool>> @where, bool issave = true)
        {
            t[] entitys = this._dbset.where(@where).toarray();
            if (entitys.length > 0)
            {
                this._dbset.removerange(entitys);
            }
            if (issave)
            {
                this.savechanges();
            }
        }

        public async task<int> aysupdate(t entity)
        {
            
            var entry = this._dbcontext.entry(entity);
            if (entry.state == entitystate.detached)
            {
                entry.state = entitystate.modified;
            }
            var da = await task.run(savechangesasync);
            return da;
        }

        public int update(t entity)
        {
            
            var entry = this._dbcontext.entry(entity);
            if (entry.state == entitystate.detached)
            {
                entry.state = entitystate.modified;
            }
            var da = savechanges();
            return da;
        }
        public void update( params t[] entitys)
        {
            var entry = this._dbcontext.entry(entitys);
            if (entry.state == entitystate.detached)
            {
                entry.state = entitystate.modified;
            }
            savechanges();
        }

        public bool any(expression<func<t, bool>> @where)
        {
            return this._dbset.asnotracking().any(@where);
        }

        public int count()
        {
            return this._dbset.asnotracking().count();
        }

        public int count(expression<func<t, bool>> @where)
        {
            return this._dbset.asnotracking().count(@where);
        }

        public t firstordefault(expression<func<t, bool>> @where)
        {
            return this._dbset.asnotracking().firstordefault(@where);
        }

        public t firstordefault<torder>(expression<func<t, bool>> @where, expression<func<t, torder>> order, bool isdesc = false)
        {
            if (isdesc)
            {
                return this._dbset.asnotracking().orderbydescending(order).firstordefault(@where);
            }
            else
            {
                return this._dbset.asnotracking().orderby(order).firstordefault(@where);
            }
        }

        public iqueryable<t> distinct(expression<func<t, bool>> @where)
        {
            return this._dbset.asnotracking().where(@where).distinct();
        }

        public iqueryable<t> where(expression<func<t, bool>> @where)
        {
            return this._dbset.where(@where);
        }

        public iqueryable<t> where<torder>(expression<func<t, bool>> @where, expression<func<t, torder>> order, bool isdesc = false)
        {
            if (isdesc)
            {
                return this._dbset.where(@where).orderbydescending(order);
            }
            else
            {
                return this._dbset.where(@where).orderby(order);
            }
        }

        public ienumerable<t> where<torder>(func<t, bool> @where, func<t, torder> order, int pageindex, int pagesize, out int count, bool isdesc = false)
        {
            count = count();
            if (isdesc)
            {
                return this._dbset.where(@where).orderbydescending(order).skip((pageindex - 1) * pagesize).take(pagesize);
            }
            else
            {
                return this._dbset.where(@where).orderby(order).skip((pageindex - 1) * pagesize).take(pagesize);
            }
        }

        public iqueryable<t> where<torder>(expression<func<t, bool>> @where, expression<func<t, torder>> order, int pageindex, int pagesize, out int count, bool isdesc = false)
        {
            count = count();
            if (isdesc)
            {
                return this._dbset.where(@where).orderbydescending(order).skip((pageindex - 1) * pagesize).take(pagesize);
            }
            else
            {
                return this._dbset.where(@where).orderby(order).skip((pageindex - 1) * pagesize).take(pagesize);
            }
        }

        public iqueryable<t> getall()
        {
            return this._dbset.asnotracking();
        }

        public iqueryable<t> getall<torder>(expression<func<t, torder>> order, bool isdesc = false)
        {
            if (isdesc)
            {
                return this._dbset.asnotracking().orderbydescending(order);
            }
            else
            {
                return this._dbset.asnotracking().orderby(order);
            }
        }

        public t getbyid<ttype>(ttype id)
        {
            return this._dbset.find(id);
        }

        public ttype max<ttype>(expression<func<t, ttype>> column)
        {
            if (this._dbset.asnotracking().any())
            {
                return this._dbset.asnotracking().max(column);
            }
            return default(ttype);
        }

        public ttype max<ttype>(expression<func<t, ttype>> column, expression<func<t, bool>> @where)
        {
            if (this._dbset.asnotracking().any(@where))
            {
                return this._dbset.asnotracking().where(@where).max(column);
            }
            return default(ttype);
        }

        public ttype min<ttype>(expression<func<t, ttype>> column)
        {
            if (this._dbset.asnotracking().any())
            {
                return this._dbset.asnotracking().min(column);
            }
            return default(ttype);
        }

        public ttype min<ttype>(expression<func<t, ttype>> column, expression<func<t, bool>> @where)
        {
            if (this._dbset.asnotracking().any(@where))
            {
                return this._dbset.asnotracking().where(@where).min(column);
            }
            return default(ttype);
        }

        public ttype sum<ttype>(expression<func<t, ttype>> selector, expression<func<t, bool>> @where) where ttype : new()
        {
            object result = 0;

            if (new ttype().gettype() == typeof(decimal))
            {
                result = this._dbset.asnotracking().where(where).sum(selector as expression<func<t, decimal>>);
            }
            if (new ttype().gettype() == typeof(decimal?))
            {
                result = this._dbset.asnotracking().where(where).sum(selector as expression<func<t, decimal?>>);
            }
            if (new ttype().gettype() == typeof(double))
            {
                result = this._dbset.asnotracking().where(where).sum(selector as expression<func<t, double>>);
            }
            if (new ttype().gettype() == typeof(double?))
            {
                result = this._dbset.asnotracking().where(where).sum(selector as expression<func<t, double?>>);
            }
            if (new ttype().gettype() == typeof(float))
            {
                result = this._dbset.asnotracking().where(where).sum(selector as expression<func<t, float>>);
            }
            if (new ttype().gettype() == typeof(float?))
            {
                result = this._dbset.asnotracking().where(where).sum(selector as expression<func<t, float?>>);
            }
            if (new ttype().gettype() == typeof(int))
            {
                result = this._dbset.asnotracking().where(where).sum(selector as expression<func<t, int>>);
            }
            if (new ttype().gettype() == typeof(int?))
            {
                result = this._dbset.asnotracking().where(where).sum(selector as expression<func<t, int?>>);
            }
            if (new ttype().gettype() == typeof(long))
            {
                result = this._dbset.asnotracking().where(where).sum(selector as expression<func<t, long>>);
            }
            if (new ttype().gettype() == typeof(long?))
            {
                result = this._dbset.asnotracking().where(where).sum(selector as expression<func<t, long?>>);
            }
            return (ttype)result;
        }

        public void dispose()
        {
            this._dbcontext.dispose();
        }
    }

三: 通过di创建实例

添加repositoryfactory类和irepositoryfactory接口

irepositoryfactory接口:

   public interface irepositoryfactory
    {
        irepositorys<t> createrepository<t>(iconcardcontext mydbcontext) where t : class;
    }

repositoryfactory类:

   public class repositoryfactory : irepositoryfactory
    {
        public irepositorys<t> createrepository<t>(iconcardcontext mydbcontext) where t : class
        {
            return new repositorys<t>(mydbcontext);
        }
    }

四:service层

添加baseservice类和ibaseservice接口

ibaseservice接口:

 public interface ibaseservice
    {
        irepositorys<t> createservice<t>() where t : class, new();
    }

baseservice类:

 public class baseservice : ibaseservice
    {
        private irepositoryfactory _repositoryfactory;
        private iconcardcontext _mydbcontext;
        public baseservice(irepositoryfactory repositoryfactory, iconcardcontext mydbcontext)
        {
            this._repositoryfactory = repositoryfactory;
            this._mydbcontext = mydbcontext;
        }

        public irepositorys<t> createservice<t>() where t : class, new()
        {
            return _repositoryfactory.createrepository<t>(_mydbcontext);
        }
    }

添加service模块xxxservice类和ixxxservice接口,xxxservice类继承父类baseservice,生成构造函数。

//构造函数 自动生成
public typechoservice(irepositoryfactory repositoryfactory, iconcardcontext mydbcontext) : base(repositoryfactory, mydbcontext)
        {
        }

五:di依赖注入配置

注册dbcontext

         services.adddbcontext<typechocontext>(options=>options.usemysql(configuration.getconnectionstring("defaultconnection")));


\\appsettings.json
     "connectionstrings": {
    "defaultconnection": "server=localhost;database=typecho;uid=root;pwd=woshishui;"
  }
services.addscoped<iconcardcontext, typechocontext>();//dbc
            services.addscoped<irepositoryfactory, repositoryfactory>();//泛型工厂
            services.addscoped<itypechotestservice, typechoservice>();//ioc

六:ui层调用service接口

testcontroller :实现调用仓储封装增删改查

 [route("api/[controller]")]
    [apicontroller]
    public class testcontroller : controller
    {
          private readonly typechocontext _coredbcontext;
          private readonly itokenhelper _tokenhelper = null;
         // itypechotestservice service = new typechoservice();
          private readonly itypechotestservice _service; //ioc依赖注入
      

        public testcontroller(typechocontext coredbcontext,itokenhelper tokenhelper,itypechotestservice service)
        {
            _coredbcontext = coredbcontext;
            _tokenhelper = tokenhelper;
            _service=service;
        }
        /// <summary>
        /// 验证token
        /// </summary>
        /// <param name="tokenstr">token</param>
        /// <returns></returns>
        [httpget("valitoken")]
        public returnmodel valitoken(string tokenstr)
        {
            var ret = new returnmodel
            {
                tntoken = new tntoken()
            };
            bool isvilidate = _tokenhelper.valitoken(tokenstr);
            if(isvilidate)
            {
                ret.code = 200;
                ret.msg = "token验证成功";
                ret.tntoken.tokenstr = tokenstr;
            }
            else
            {
                ret.code = 500;
                ret.msg = "token验证失败";
                ret.tntoken.tokenstr = tokenstr;
            }
            return ret;
        }
        /// <summary>
        /// 验证token 带返回状态
        /// </summary>
        /// <param name="tokenstr"></param>
        /// <returns></returns>
        [httpget("valitokenstate")]
        public returnmodel valitokenstate(string tokenstr)
        {
            var ret = new returnmodel
            {
                tntoken = new tntoken()
            };
            string loginid = "";
            tokentype tokentype = _tokenhelper.valitokenstate(tokenstr, a => a["iss"] == "wyy" && a["aud"] == "everytestone", action => { loginid = action["loginid"]; });
            if (tokentype == tokentype.fail)
            {
                ret.code = 202;
                ret.msg = "token验证失败";
                return ret;
            }
            if (tokentype == tokentype.expired)
            {
                ret.code = 205;
                ret.msg = "token已经过期";
                return ret;
            }

            //..............其他逻辑
            var data = new list<dictionary<string, string>>();
            var bb = new dictionary<string, string>
            {
                { "wyy", "123456" }
            };
            data.add(bb);
            ret.code = 200;
            ret.msg = "访问成功!";
            ret.data =data ;
            return ret;
        }

        /// <summary>
        /// 登录测试
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
         [httppost("login")]
        public iactionresult login([frombody]logininput user)
        {
            var ret = new returnmodel();
            try
            {
                if (string.isnullorwhitespace(user.username) || string.isnullorwhitespace(user.password))
                {
                    ret.code = 201;
                    ret.msg = "用户名密码不能为空";
                    return notfound();
                }
                //登录操作 我就没写了 || 假设登录成功
                if (true)
                {
                    dictionary<string, string> keyvaluepairs = new dictionary<string, string>
                    {
                        { "loginid", user.username }
                    };
                    ret.code = 200;
                    ret.msg = "登录成功";
                    ret.tntoken= _tokenhelper.createtoken(keyvaluepairs);
                }
            }
            catch(exception ex)
            {
                ret.code = 500;
                ret.msg = "登录失败:"+ex.message;
            }
            return ok(ret);
        }

        /// <summary>
        /// 异步查询
        /// [apiexplorersettings(ignoreapi = true)] 隐藏接口
        /// </summary>
        /// <returns></returns>
        [servicefilter(typeof(tokenfilter))]
        [httpget("asygettest")]
        public async task<iactionresult> asygettest(string token)
        {
          return ok(await _service.asygettest());
        }

         /// <summary>
        /// 同步查询
        /// </summary>
        /// <returns></returns>
        [httpget("gettest")]
        public iactionresult gettest()
        {
          return ok(_service.gettest());
         }

         /// <summary>
         /// 条件查询
         /// </summary>
         /// <returns></returns>
         [httpget("asygettestname")]
        public async task<iactionresult> asygettestname(int id)
        {
            return ok(await _service.asygettestname(id));
        }

         /// <summary>
        /// 过滤查询
        /// </summary>
        /// <returns></returns>
        [httpget("asygettestg")]
        public async task<iactionresult> asygettestg(string name )
        {
              var courses = _coredbcontext.typecho_test
                  .where(w => w.name.contains(name));
            return ok( await courses.firstasync());
        }

        /// <summary>
        /// 模糊查询
        /// </summary>
        /// <returns></returns>
        [httpget("asygettestlink")]
        public async task<iactionresult> asygettestlink(string name )
        {
              var courses = _coredbcontext.typecho_test
                  .where(w=>ef.functions.like(w.name,"%"));
            return ok( await courses.tolistasync());
        }


        /// <summary>
        /// 异步删除数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [httpdelete("asydettestid")]
        public async task<iactionresult> asydettestid(int id)
        {
          return ok(await _service.asydettestid(id));
        }

        /// <summary>
        /// 同步删除数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [httpdelete("dettestid")]
        public  iactionresult dettestid(int id)
        {
          return ok( _service.dettestid(id));
        }
        
        /// <summary>
        /// 异步添加数据
        /// </summary>
        /// <returns></returns>
        [httppost("asyinttest")]
        public async task<actionresult<typecho_test>> asyinttest(typecho_test test)
        {
            return ok(await _service.asyinttest(test));
        }
          
        /// <summary>
        /// 同步添加数据
        /// </summary>
        /// <returns></returns>
        [httppost("inttest")]
        public  actionresult<typecho_test> inttest(typecho_test test)
        {
            return ok(_service.inttest(test));
        }

        /// <summary>
        /// 异步更新数据
        /// </summary>
        /// <param name="test"></param>
        /// <returns></returns>
        [httpput("aysuptest")]
        public async task<iactionresult> aysuptest(typecho_test test)
        {
           var data=await task.run(()=> _service.aysuptest(test));
           return ok(data);
        }

        /// <summary>
        /// 同步更新数据
        /// </summary>
        /// <param name="id"></param>
        /// <param name="test"></param>
        /// <returns></returns>
        [httpput("uptest")]
        public  iactionresult uptest(int id, typecho_test test)
        { 
            var data= _service.uptest(test);
           return ok(data);
        }
    }

图示

NetCore3.1webApi + EFCore + DI 框架封装

NetCore3.1webApi + EFCore + DI 框架封装

参考:.net core2.2 + ef core + di,三层框架项目搭建教程