zoukankan      html  css  js  c++  java
  • .net core

    近两年.Net Core发展的很快,目前最新版为3.0预览版,之前在网上买了一本1.1版书籍都还没来得及看呢,估计现在拿出来看也毫无意义了。已多年.net工作经验,看书不如直接实际上手来得快,遇到问题再度娘吧。正好最近公司不忙时,抽空亲手搭建.Net Core项目熟悉一下,说起.net那最自豪的就是VS编译器了,强大的辅助功能很多中小型项目只需要下一步就可以创建完成。这里我们还需要简单封装一下,使用仓储模式对数据访问层封装和Service层封装,通过.net自带DI依赖注入进行创建对象。对于初学者的我只能简单的封装一下,接下来我会一一讲解框架的思路,如有更好的方案或不明的地方欢迎留言。转载请备注来源:https://www.cnblogs.com/han1982/p/11058788.html

    下面是已搭建好的框架结构:

    第一步:创建解决方案

    使用Visual Studio 2019编译器创建解决方案,默认安装vs2019自带的.NET Core 2.1,创建.NET Core 2.2版需要下载SDK安装。

    https://dotnet.microsoft.com/download/visual-studio-sdks?utm_source=getdotnetsdk&utm_medium=referral

    接下来可以创建项目了,首先创建的是数据访问层,我们命名为common.Core,另外给他创建一个接口层common.Interface。

    (注意所有程序集创建必须为.Net Core版,为以后发布垮平台考虑)

    第二步:创建Model层

    封装仓储层之前先来创建数据Model层,Nuget添加EF Core相关引用,工具 - NuGet包管理器 - 程序包管理器控制台,默认项目选择Model程序集依次安装以下组件包。

    Install-Package Microsoft.EntityFrameworkCore -version 2.2.4

    Install-Package Microsoft.EntityFrameworkCore.SqlServer -version 2.2.4

    Install-Package Microsoft.EntityFrameworkCore.Tools -version 2.2.4

    也可以在项目中找到依赖项,右键管理NuGet管理包方式进行添加。

    Microsoft.EntityFrameworkCore.Tools中包含了Microsoft.EntityFrameworkCore.Design依赖包,不需要单独安装了。

    这里我使用的是Database First模式,使用工具Scaffold-DbContext(数据库上下文脚手架)来生成model类文件和DbContext。

    执行以下命令:-o (OutputDir) 指定用于输出类的目录 -f (Force) 生成时覆盖现有文件 -Context 指定生成的DbContext类的名称,省略的话按数据库名称生成DbContext类文件。

    Scaffold-DbContext "server=.;database=ConCard;uid=sa;pwd=123123;" Microsoft.EntityFrameworkCore.SqlServer -O Models -F

    出现错误:VS2019有个小小BUG,默认项目选中以后最终执行的不是被选中程序集,这里需要把model程序集设为启动项目,再次执行。

    自动生成所有类模型文件,ConCardContext.cs数据库上下文也都帮你创建好了,这样就省去了我们手动写DBSet时间。

    第三步:封装数据访问层

    数据访问层主要封装仓储Repository和工作单元UnitOfWork,我把这两个合并到一个类中实现,通过简单工厂方式创建实例对象。

    我们直接把ConCardContext.cs这个类复制到common.Core程序集中,把命名空间修改为common.Core。

    这时应该报错,因为common.Core项目中没有引用EFCore依赖包,按之前Model层添加一样,使用Install-Package命令为common.Core添加依赖包,Tools可以不用安装。

    依赖项中,右键添加引用,把Model和common.Interface项目引用,ConCardContext.cs中using model就不会报错了。

    接下来修改下ConCardContext:

    重写SaveChanges方法

    publicoverrideintSaveChanges

    {

    returnbase.SaveChanges( true);

    }

    删除OnConfiguring方法,因为我们不需要在这里配置数据库连接,后面通过读取配置方式设置。

    protectedoverridevoidOnConfiguring(DbContextOptionsBuilder optionsBuilder)

    {

    if(! optionsBuilder.IsConfigured)

    {

    optionsBuilder.UseSqlServer("server=.;database=ConCard;uid=sa;pwd=123123;");

    }

    }

    common.Interface程序集中创建IconcardContext接口,ConCardContext类中继承自这个接口。(主要用来后期使用DI依赖注入使用,不用接口也可以用DbContext代替)

    ConCardContext类:

    usingSystem;

    usingcom.Synjones.Model.Models;

    usingcommon.Interface;

    usingMicrosoft.EntityFrameworkCore;

    usingMicrosoft.EntityFrameworkCore.Metadata;

    namespacecommon.Core

    {

    publicpartialclassConCardContext : DbContext, IconcardContext

    {

    publicConCardContext

    {

    }

    publicConCardContext(DbContextOptions<ConCardContext> options)

    : base(options)

    {

    }

    publicoverrideintSaveChanges

    {

    returnbase.SaveChanges( true);

    }

    publicvirtualDbSet<Admin> Admin { get; set; }

    publicvirtualDbSet<User> User { get; set; }

    protectedoverridevoidOnModelCreating(ModelBuilder modelBuilder)

    {

    modelBuilder.HasAnnotation("ProductVersion", "2.2.4-servicing-10062");

    modelBuilder.Entity<Admin>(entity =>

    {

    entity.Property(e => e.PassWord).HasMaxLength( 50);

    entity.Property(e => e.UserId).HasMaxLength( 50);

    });

    modelBuilder.Entity<User>(entity =>

    {

    entity.Property(e => e.Name).HasMaxLength( 50);

    entity.Property(e => e.Phone).HasMaxLength( 50);

    });

    }

    }

    }

    开始继续创建Repository.cs仓储类,它是一个泛型类,并且拥有一个带有参数的构造方法,通过构造方法获得当前DbContext上下文对象,泛型类为指定Model类型,通过DbContext.Set<T>方法最终得到相应的DbSet<T>对象来操作工作单元。

    当然我们也要给他定义一个接口IRepository接口:

    usingSystem;

    usingSystem.Collections.Generic;

    usingSystem.Data;

    usingSystem.Linq;

    usingSystem.Linq.Expressions;

    usingSystem.Text;

    namespacecommon.Interface

    {

    publicinterfaceIRepository<T> : IDisposable whereT : class

    {

    ///<summary>

    ///显式开启数据上下文事务

    ///</summary>

    ///<param name="isolationLevel">指定连接的事务锁定行为</param>

    voidBeginTransaction(IsolationLevel isolationLevel = IsolationLevel.Unspecified);

    ///<summary>

    ///提交事务的更改

    ///</summary>

    voidCommit;

    ///<summary>

    ///显式回滚事务,仅在显式开启事务后有用

    ///</summary>

    voidRollback;

    ///<summary>

    ///提交当前单元操作的更改

    ///</summary>

    intSaveChanges;

    ///<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, boolisSave = true);

    ///<summary>

    ///批量插入 - 通过实体对象集合添加

    ///</summary>

    ///<param name="entitys">实体对象集合</param>

    ///<param name="isSave">是否执行</param>

    voidAddRange(IEnumerable<T> entitys, boolisSave = true);

    ///<summary>

    ///删除 - 通过实体对象删除

    ///</summary>

    ///<param name="entity">实体对象</param>

    ///<param name="isSave">是否执行</param>

    voidDelete(T entity, boolisSave = true);

    ///<summary>

    ///批量删除 - 通过实体对象集合删除

    ///</summary>

    ///<param name="entitys">实体对象集合</param>

    ///<param name="isSave">是否执行</param>

    voidDelete( boolisSave = false, paramsT[] entitys);

    ///<summary>

    ///删除 - 通过主键ID删除

    ///</summary>

    ///<param name="id">主键ID</param>

    ///<param name="isSave">是否执行</param>

    voidDelete( objectid, boolisSave = true);

    ///<summary>

    ///批量删除 - 通过条件删除

    ///</summary>

    ///<param name="where">过滤条件</param>

    ///<param name="isSave">是否执行</param>

    voidDelete(Expression<Func<T, bool>> @where, boolisSave = true);

    ///<summary>

    ///修改 - 通过实体对象修改

    ///</summary>

    ///<param name="entity">实体对象</param>

    ///<param name="isSave"></param>

    voidUpdate(T entity, boolisSave = true);

    ///<summary>

    ///批量修改 - 通过实体对象集合修改

    ///</summary>

    ///<param name="entitys">实体对象集合</param>

    ///<param name="isSave"></param>

    voidUpdate( boolisSave = true, paramsT[] entitys);

    ///<summary>

    ///是否满足条件

    ///</summary>

    ///<param name="where">过滤条件</param>

    ///<returns></returns>

    boolAny(Expression<Func<T, bool>> @where);

    ///<summary>

    ///返回总条数

    ///</summary>

    ///<returns></returns>

    intCount;

    ///<summary>

    ///返回总条数 - 通过条件过滤

    ///</summary>

    ///<param name="where">过滤条件</param>

    ///<returns></returns>

    intCount(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, boolisDesc = 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, boolisDesc = 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, intpageIndex, intpageSize, outintcount, boolisDesc = 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, intpageIndex, intpageSize, outintcount, boolisDesc = 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, boolisDesc = 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) whereTType : new;

    }

    }

    Repository类,实现了CRUD基本功能的封装:

    usingcommon.Interface;

    usingMicrosoft.EntityFrameworkCore;

    usingSystem;

    usingSystem.Collections.Generic;

    usingSystem.Data;

    usingSystem.Data.SqlClient;

    usingSystem.Linq;

    usingSystem.Linq.Expressions;

    usingSystem.Text;

    namespacecommon.Core

    {

    publicclassRepository<T> : IRepository<T> whereT : class

    {

    privateConCardContext _dbContext;

    privatereadonlyDbSet<T> _dbSet;

    privatereadonlystring_connStr;

    publicRepository(IconcardContext mydbcontext)

    {

    this._dbContext = mydbcontext asConCardContext;

    this._dbSet = _dbContext.Set<T> ;

    this._connStr = _dbContext.Database.GetDbConnection.ConnectionString;

    }

    publicvoidBeginTransaction(IsolationLevel isolationLevel = IsolationLevel.Unspecified)

    {

    if( this._dbContext.Database.CurrentTransaction == null)

    {

    this._dbContext.Database.BeginTransaction(isolationLevel);

    }

    }

    publicvoidCommit

    {

    vartransaction = this._dbContext.Database.CurrentTransaction;

    if(transaction != null)

    {

    try

    {

    transaction.Commit;

    }

    catch(Exception)

    {

    transaction.Rollback;

    throw;

    }

    }

    }

    publicvoidRollback

    {

    if( this._dbContext.Database.CurrentTransaction != null)

    {

    this._dbContext.Database.CurrentTransaction.Rollback;

    }

    }

    publicintSaveChanges

    {

    returnthis._dbContext.SaveChanges;

    }

    publicIQueryable<T> Entities

    {

    get{ returnthis._dbSet.AsNoTracking; }

    }

    publicIQueryable<T> TrackEntities

    {

    get{ returnthis._dbSet; }

    }

    publicT Add(T entity, boolisSave = true)

    {

    this._dbSet.Add(entity);

    if(isSave)

    {

    this.SaveChanges;

    }

    returnentity;

    }

    publicvoidAddRange(IEnumerable<T> entitys, boolisSave = true)

    {

    this._dbSet.AddRange(entitys);

    if(isSave)

    {

    this.SaveChanges;

    }

    }

    publicvoidDelete(T entity, boolisSave = true)

    {

    this._dbSet.Remove(entity);

    if(isSave)

    {

    this.SaveChanges;

    }

    }

    publicvoidDelete( boolisSave = true, paramsT[] entitys)

    {

    this._dbSet.RemoveRange(entitys);

    if(isSave)

    {

    this.SaveChanges;

    }

    }

    publicvoidDelete( objectid, boolisSave = true)

    {

    this._dbSet.Remove( this._dbSet.Find(id));

    if(isSave)

    {

    this.SaveChanges;

    }

    }

    publicvoidDelete(Expression<Func<T, bool>> @where, boolisSave = true)

    {

    T[] entitys = this._dbSet.Where<T> (@where).ToArray;

    if(entitys.Length > 0)

    {

    this._dbSet.RemoveRange(entitys);

    }

    if(isSave)

    {

    this.SaveChanges;

    }

    }

    publicvoidUpdate(T entity, boolisSave = true)

    {

    varentry = this._dbContext.Entry(entity);

    if(entry.State == EntityState.Detached)

    {

    entry.State = EntityState.Modified;

    }

    if(isSave)

    {

    this.SaveChanges;

    }

    }

    publicvoidUpdate( boolisSave = true, paramsT[] entitys)

    {

    varentry = this._dbContext.Entry(entitys);

    if(entry.State == EntityState.Detached)

    {

    entry.State = EntityState.Modified;

    }

    if(isSave)

    {

    this.SaveChanges;

    }

    }

    publicboolAny(Expression<Func<T, bool>> @where)

    {

    returnthis._dbSet.AsNoTracking.Any(@where);

    }

    publicintCount

    {

    returnthis._dbSet.AsNoTracking.Count;

    }

    publicintCount(Expression<Func<T, bool>> @where)

    {

    returnthis._dbSet.AsNoTracking.Count(@where);

    }

    publicT FirstOrDefault(Expression<Func<T, bool>> @where)

    {

    returnthis._dbSet.AsNoTracking.FirstOrDefault(@where);

    }

    publicT FirstOrDefault<TOrder>(Expression<Func<T, bool>> @where, Expression<Func<T, TOrder>> order, boolisDesc = false)

    {

    if(isDesc)

    {

    returnthis._dbSet.AsNoTracking.OrderByDescending(order).FirstOrDefault(@where);

    }

    else

    {

    returnthis._dbSet.AsNoTracking.OrderBy(order).FirstOrDefault(@where);

    }

    }

    publicIQueryable<T> Distinct(Expression<Func<T, bool>> @where)

    {

    returnthis._dbSet.AsNoTracking.Where(@where).Distinct;

    }

    publicIQueryable<T> Where(Expression<Func<T, bool>> @where)

    {

    returnthis._dbSet.Where(@where);

    }

    publicIQueryable<T> Where<TOrder>(Expression<Func<T, bool>> @where, Expression<Func<T, TOrder>> order, boolisDesc = false)

    {

    if(isDesc)

    {

    returnthis._dbSet.Where(@where).OrderByDescending(order);

    }

    else

    {

    returnthis._dbSet.Where(@where).OrderBy(order);

    }

    }

    publicIEnumerable<T> Where<TOrder>(Func<T, bool> @where, Func<T, TOrder> order, intpageIndex, intpageSize, outintcount, boolisDesc = false)

    {

    count = Count;

    if(isDesc)

    {

    returnthis._dbSet.Where(@where).OrderByDescending(order).Skip((pageIndex - 1) * pageSize).Take(pageSize);

    }

    else

    {

    returnthis._dbSet.Where(@where).OrderBy(order).Skip((pageIndex - 1) * pageSize).Take(pageSize);

    }

    }

    publicIQueryable<T> Where<TOrder>(Expression<Func<T, bool>> @where, Expression<Func<T, TOrder>> order, intpageIndex, intpageSize, outintcount, boolisDesc = false)

    {

    count = Count;

    if(isDesc)

    {

    returnthis._dbSet.Where(@where).OrderByDescending(order).Skip((pageIndex - 1) * pageSize).Take(pageSize);

    }

    else

    {

    returnthis._dbSet.Where(@where).OrderBy(order).Skip((pageIndex - 1) * pageSize).Take(pageSize);

    }

    }

    publicIQueryable<T> GetAll

    {

    returnthis._dbSet.AsNoTracking;

    }

    publicIQueryable<T> GetAll<TOrder>(Expression<Func<T, TOrder>> order, boolisDesc = false)

    {

    if(isDesc)

    {

    returnthis._dbSet.AsNoTracking.OrderByDescending(order);

    }

    else

    {

    returnthis._dbSet.AsNoTracking.OrderBy(order);

    }

    }

    publicT GetById<Ttype> (Ttype id)

    {

    returnthis._dbSet.Find(id);

    }

    publicTtype Max<Ttype>(Expression<Func<T, Ttype>> column)

    {

    if( this._dbSet.AsNoTracking.Any)

    {

    returnthis._dbSet.AsNoTracking.Max<T, Ttype> (column);

    }

    returndefault(Ttype);

    }

    publicTtype Max<Ttype>(Expression<Func<T, Ttype>> column, Expression<Func<T, bool>> @where)

    {

    if( this._dbSet.AsNoTracking.Any(@where))

    {

    returnthis._dbSet.AsNoTracking.Where(@where).Max<T, Ttype> (column);

    }

    returndefault(Ttype);

    }

    publicTtype Min<Ttype>(Expression<Func<T, Ttype>> column)

    {

    if( this._dbSet.AsNoTracking.Any)

    {

    returnthis._dbSet.AsNoTracking.Min<T, Ttype> (column);

    }

    returndefault(Ttype);

    }

    publicTtype Min<Ttype>(Expression<Func<T, Ttype>> column, Expression<Func<T, bool>> @where)

    {

    if( this._dbSet.AsNoTracking.Any(@where))

    {

    returnthis._dbSet.AsNoTracking.Where(@where).Min<T, Ttype> (column);

    }

    returndefault(Ttype);

    }

    publicTType Sum<TType>(Expression<Func<T, TType>> selector, Expression<Func<T, bool>> @where) whereTType : new

    {

    objectresult = 0;

    if( newTType.GetType == typeof( decimal))

    {

    result = this._dbSet.AsNoTracking.Where( where).Sum(selector asExpression<Func<T, decimal>> );

    }

    if( newTType.GetType == typeof( decimal? ))

    {

    result = this._dbSet.AsNoTracking.Where( where).Sum(selector asExpression<Func<T, decimal?>> );

    }

    if( newTType.GetType == typeof( double))

    {

    result = this._dbSet.AsNoTracking.Where( where).Sum(selector asExpression<Func<T, double>> );

    }

    if( newTType.GetType == typeof( double? ))

    {

    result = this._dbSet.AsNoTracking.Where( where).Sum(selector asExpression<Func<T, double?>> );

    }

    if( newTType.GetType == typeof( float))

    {

    result = this._dbSet.AsNoTracking.Where( where).Sum(selector asExpression<Func<T, float>> );

    }

    if( newTType.GetType == typeof( float? ))

    {

    result = this._dbSet.AsNoTracking.Where( where).Sum(selector asExpression<Func<T, float?>> );

    }

    if( newTType.GetType == typeof( int))

    {

    result = this._dbSet.AsNoTracking.Where( where).Sum(selector asExpression<Func<T, int>> );

    }

    if( newTType.GetType == typeof( int? ))

    {

    result = this._dbSet.AsNoTracking.Where( where).Sum(selector asExpression<Func<T, int?>> );

    }

    if( newTType.GetType == typeof( long))

    {

    result = this._dbSet.AsNoTracking.Where( where).Sum(selector asExpression<Func<T, long>> );

    }

    if( newTType.GetType == typeof( long? ))

    {

    result = this._dbSet.AsNoTracking.Where( where).Sum(selector asExpression<Func<T, long?>> );

    }

    return(TType)result;

    }

    publicvoidDispose

    {

    this._dbContext.Dispose;

    }

    }

    }

    这样仓储模式就创建好了,接下来想办法通过DI创建实例,而不是直接在Service层new一个实例,但是Repository是泛型类,通过DI创建需要设置,所有不同model类都要声明一遍,这里只能使用简单工厂来处理下。

    添加RepositoryFactory类和IRepositoryFactory接口,接口中定义IRepository<T> CreateRepository<T>(IconcardContext mydbcontext) where T : class; 通过实现CreateRepository方法来创建不同数据模型的工作单元。

    IRepositoryFactory接口:

    usingSystem;

    usingSystem.Collections.Generic;

    usingSystem.Text;

    namespacecommon.Interface

    {

    publicinterfaceIRepositoryFactory

    {

    IRepository<T> CreateRepository<T>(IconcardContext mydbcontext) whereT : class;

    }

    }

    RepositoryFactory类:

    usingcommon.Interface;

    usingSystem;

    usingSystem.Collections.Generic;

    usingSystem.Text;

    namespacecommon.Core

    {

    publicclassRepositoryFactory : IRepositoryFactory

    {

    publicIRepository<T> CreateRepository<T>(IconcardContext mydbcontext) whereT : class

    {

    returnnewRepository<T> (mydbcontext);

    }

    }

    }

    第四步:创建Service层:

    老规矩,先添加新建项目Service和IService,一个是定义Service接口,另一个是它的实现,他们都需要引入Model层和Interface层,Service要引入IService层。

    添加BaseService类和IBaseService接口,接口中定义IRepository<T> CreateService<T> where T : class, new;

    IBaseService接口:

    usingcommon.Interface;

    usingSystem;

    usingSystem.Collections.Generic;

    usingSystem.Text;

    namespacecom.Synjones.IService

    {

    publicinterfaceIBaseService

    {

    IRepository<T> CreateService<T> whereT : class, new;

    }

    }

    BaseService类:

    usingcom.Synjones.IService;

    usingcommon.Interface;

    usingSystem;

    usingSystem.Collections.Generic;

    usingSystem.Text;

    namespacecom.Synjones.Service

    {

    publicclassBaseService : IBaseService

    {

    privateIRepositoryFactory _repositoryFactory;

    privateIconcardContext _mydbcontext;

    publicBaseService(IRepositoryFactory repositoryFactory, IconcardContext mydbcontext)

    {

    this._repositoryFactory = repositoryFactory;

    this._mydbcontext = mydbcontext;

    }

    publicIRepository<T> CreateService<T> whereT : class, new

    {

    return_repositoryFactory.CreateRepository<T> (_mydbcontext);

    }

    }

    }

    这里说明一下,BaseService类也是泛型类,也不需要通过DI方式创建,Service层中根据每个模块添加一个Service类,并且继承BaseService类,DI依赖注入模块Service中直接获取到指定模型的仓储进行操作。

    添加User模块UserService类和IUserService接口,UserService类继承父类BaseService,生成构造函数。

    publicUserService(IRepositoryFactory repositoryFactory, IconcardContext mydbcontext) : base(repositoryFactory, mydbcontext)

    {

    }

    下面我们简单举例对user表读取操作的业务层实现,定义接口List<User> GetUsers,实现GetUsers方法,读取所有user表数据。

    IUserService接口:

    usingcom.Synjones.Model.Models;

    usingSystem;

    usingSystem.Collections.Generic;

    usingSystem.Text;

    namespacecom.Synjones.IService

    {

    publicinterfaceIUserService

    {

    List<User> GetUsers;

    }

    }

    UserService类:

    usingcom.Synjones.IService;

    usingcom.Synjones.Model.Models;

    usingcommon.Interface;

    usingSystem;

    usingSystem.Collections.Generic;

    usingSystem.Text;

    usingSystem.Linq;

    namespacecom.Synjones.Service

    {

    publicclassUserService : BaseService, IUserService

    {

    publicUserService(IRepositoryFactory repositoryFactory, IconcardContext mydbcontext) : base(repositoryFactory, mydbcontext)

    {

    }

    publicList<User> GetUsers

    {

    varservice = this.CreateService<User> ;

    returnservice.GetAll.ToList;

    }

    }

    }

    第五步:UI创建并调用Service接口返回数据。

    我这里创建了WebApi项目,依赖项中添加引用所有其他项目。

    配置数据库连接字符串,打开appsettings.json,添加

    "ConnectionStrings": {

    "SchoolConnection": "server=.;database=ConCard;uid=sa;pwd=123123;"

    }

    配置EF服务注册:

    打开Startup.cs,ConfigureServices方法中添加services.AddDbContext指定数据库连接配置项,通过services.AddScoped添加DI依赖注入配置。

    publicvoidConfigureServices(IServiceCollection services)

    {

    services.AddMvc.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

    //配置EF服务注册

    services.AddDbContext<common.Core.ConCardContext>(options =>

    options.UseSqlServer(Configuration.GetConnectionString("SchoolConnection")));

    services.AddScoped<IconcardContext, common.Core.ConCardContext> ;

    services.AddScoped<IRepositoryFactory, RepositoryFactory> ;

    services.AddScoped<IUserService, UserService> ;

    }

    修改下ValuesController控制器,添加构造函数和Get方法。

    WebApi项目设为启动项目,运行看结果。

  • 相关阅读:
    速达5000出现计算成本数据溢出的问题
    速达软件 移动端 App 功能说明
    无法打开物理文件 操作系统错误 5: 5(拒绝访问。) 问题解决
    速达软件开发版使用技巧-销售开单单据打印格式设计
    开发版速达软件如何进行有效授权
    速达软件 移动端 App 下载试用
    速达软件二次开发-试用版本下载,欢迎合作
    速达软件开发版使用技巧-每页固定行样式报表设计
    Cause: org.postgresql.util.PSQLException: 栏位索引超过许可范围:13,栏位数:12
    springboot 开启事务回滚
  • 原文地址:https://www.cnblogs.com/ransom/p/12750946.html
Copyright © 2011-2022 走看看