筆記:html
近兩年.Net Core發展的很快,目前最新版爲3.0預覽版,以前在網上買了一本1.1版書籍都還沒來得及看呢,估計如今拿出來看也毫無心義了。已多年.net工做經驗,看書不如直接實際上手來得快,遇到問題再度娘吧。正好最近公司不忙時,抽空親手搭建.Net Core項目熟悉一下,提及.net那最自豪的就是VS編譯器了,強大的輔助功能不少中小型項目只須要下一步就能夠建立完成。這裏咱們還須要簡單封裝一下,使用倉儲模式對數據訪問層封裝和Service層封裝,經過.net自帶DI依賴注入進行建立對象。對於初學者的我只能簡單的封裝一下,接下來我會一一講解框架的思路,若有更好的方案或不明的地方歡迎留言。轉載請備註來源:http://www.javashuo.com/article/p-gtxzjzew-hq.html數據庫
下面是已搭建好的框架結構:json
第一步:建立解決方案app
使用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=referralide
接下來能夠建立項目了,首先建立的是數據訪問層,咱們命名爲common.Core,另外給他建立一個接口層common.Interface。函數
(注意全部程序集建立必須爲.Net Core版,爲之後發佈垮平臺考慮)工具
第二步:建立Model層visual-studio
封裝倉儲層以前先來建立數據Model層,Nuget添加EF Core相關引用,工具 - NuGet包管理器 - 程序包管理器控制檯,默認項目選擇Model程序集依次安裝如下組件包。ui
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()方法
public override int SaveChanges() { return base.SaveChanges(true); }
刪除OnConfiguring()方法,由於咱們不須要在這裏配置數據庫鏈接,後面經過讀取配置方式設置。
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (!optionsBuilder.IsConfigured) { optionsBuilder.UseSqlServer("server=.;database=ConCard;uid=sa;pwd=123123;"); } }
common.Interface程序集中建立IconcardContext接口,ConCardContext類中繼承自這個接口。(主要用來後期使用DI依賴注入使用,不用接口也能夠用DbContext代替)
ConCardContext類:
using System; using com.Synjones.Model.Models; using common.Interface; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; namespace common.Core { public partial class ConCardContext : DbContext, IconcardContext { public ConCardContext() { } public ConCardContext(DbContextOptions<ConCardContext> options) : base(options) { } public override int SaveChanges() { return base.SaveChanges(true); } public virtual DbSet<Admin> Admin { get; set; } public virtual DbSet<User> User { get; set; } protected override void OnModelCreating(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接口:
using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Linq.Expressions; using System.Text; namespace common.Interface { public interface IRepository<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(); /// <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); /// <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> /// <param name="isSave">是否執行</param> void Delete(object id, bool isSave = true); /// <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> /// <param name="isSave"></param> void Update(T entity, bool isSave = true); /// <summary> /// 批量修改 - 經過實體對象集合修改 /// </summary> /// <param name="entitys">實體對象集合</param> /// <param name="isSave"></param> void Update(bool isSave = true, 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(); } }
Repository類,實現了CRUD基本功能的封裝:
using common.Interface; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Linq.Expressions; using System.Text; namespace common.Core { public class Repository<T> : IRepository<T> where T : class { private ConCardContext _dbContext; private readonly DbSet<T> _dbSet; private readonly string _connStr; public Repository(IconcardContext mydbcontext) { this._dbContext = mydbcontext as ConCardContext; this._dbSet = _dbContext.Set<T>(); this._connStr = _dbContext.Database.GetDbConnection().ConnectionString; } public void BeginTransaction(IsolationLevel isolationLevel = IsolationLevel.Unspecified) { if (this._dbContext.Database.CurrentTransaction == null) { this._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 (this._dbContext.Database.CurrentTransaction != null) { this._dbContext.Database.CurrentTransaction.Rollback(); } } public int SaveChanges() { return this._dbContext.SaveChanges(); } public IQueryable<T> Entities { get { return this._dbSet.AsNoTracking(); } } public IQueryable<T> TrackEntities { get { return this._dbSet; } } public T Add(T entity, bool isSave = true) { this._dbSet.Add(entity); if (isSave) { this.SaveChanges(); } return entity; } public void AddRange(IEnumerable<T> entitys, bool isSave = true) { this._dbSet.AddRange(entitys); if (isSave) { this.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 void Delete(object id, bool isSave = true) { this._dbSet.Remove(this._dbSet.Find(id)); if (isSave) { this.SaveChanges(); } } public void Delete(Expression<Func<T, bool>> @where, bool isSave = true) { T[] entitys = this._dbSet.Where<T>(@where).ToArray(); if (entitys.Length > 0) { this._dbSet.RemoveRange(entitys); } if (isSave) { this.SaveChanges(); } } public void Update(T entity, bool isSave = true) { var entry = this._dbContext.Entry(entity); if (entry.State == EntityState.Detached) { entry.State = EntityState.Modified; } if (isSave) { this.SaveChanges(); } } public void Update(bool isSave = true, params T[] entitys) { var entry = this._dbContext.Entry(entitys); if (entry.State == EntityState.Detached) { entry.State = EntityState.Modified; } if (isSave) { this.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<T, Ttype>(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<T, Ttype>(column); } return default(Ttype); } public Ttype Min<Ttype>(Expression<Func<T, Ttype>> column) { if (this._dbSet.AsNoTracking().Any()) { return this._dbSet.AsNoTracking().Min<T, Ttype>(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<T, Ttype>(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建立實例,而不是直接在Service層new一個實例,可是Repository是泛型類,經過DI建立須要設置,全部不一樣model類都要聲明一遍,這裏只能使用簡單工廠來處理下。
添加RepositoryFactory類和IRepositoryFactory接口,接口中定義IRepository<T> CreateRepository<T>(IconcardContext mydbcontext) where T : class; 經過實現CreateRepository方法來建立不一樣數據模型的工做單元。
IRepositoryFactory接口:
using System; using System.Collections.Generic; using System.Text; namespace common.Interface { public interface IRepositoryFactory { IRepository<T> CreateRepository<T>(IconcardContext mydbcontext) where T : class; } }
RepositoryFactory類:
using common.Interface; using System; using System.Collections.Generic; using System.Text; namespace common.Core { public class RepositoryFactory : IRepositoryFactory { public IRepository<T> CreateRepository<T>(IconcardContext mydbcontext) where T : class { return new Repository<T>(mydbcontext); } } }
第四步:建立Service層:
老規矩,先添加新建項目Service和IService,一個是定義Service接口,另外一個是它的實現,他們都須要引入Model層和Interface層,Service要引入IService層。
添加BaseService類和IBaseService接口,接口中定義IRepository<T> CreateService<T>() where T : class, new();
IBaseService接口:
using common.Interface; using System; using System.Collections.Generic; using System.Text; namespace com.Synjones.IService { public interface IBaseService { IRepository<T> CreateService<T>() where T : class, new(); } }
BaseService類:
using com.Synjones.IService; using common.Interface; using System; using System.Collections.Generic; using System.Text; namespace com.Synjones.Service { public class BaseService : IBaseService { private IRepositoryFactory _repositoryFactory; private IconcardContext _mydbcontext; public BaseService(IRepositoryFactory repositoryFactory, IconcardContext mydbcontext) { this._repositoryFactory = repositoryFactory; this._mydbcontext = mydbcontext; } public IRepository<T> CreateService<T>() where T : class, new() { return _repositoryFactory.CreateRepository<T>(_mydbcontext); } } }
這裏說明一下,BaseService類也是泛型類,也不須要經過DI方式建立,Service層中根據每一個模塊添加一個Service類,而且繼承BaseService類,DI依賴注入模塊Service中直接獲取到指定模型的倉儲進行操做。
添加User模塊UserService類和IUserService接口,UserService類繼承父類BaseService,生成構造函數。
public UserService(IRepositoryFactory repositoryFactory, IconcardContext mydbcontext) : base(repositoryFactory, mydbcontext) { }
下面咱們簡單舉例對user表讀取操做的業務層實現,定義接口List<User> GetUsers(),實現GetUsers()方法,讀取全部user表數據。
IUserService接口:
using com.Synjones.Model.Models; using System; using System.Collections.Generic; using System.Text; namespace com.Synjones.IService { public interface IUserService { List<User> GetUsers(); } }
UserService類:
using com.Synjones.IService; using com.Synjones.Model.Models; using common.Interface; using System; using System.Collections.Generic; using System.Text; using System.Linq; namespace com.Synjones.Service { public class UserService : BaseService, IUserService { public UserService(IRepositoryFactory repositoryFactory, IconcardContext mydbcontext) : base(repositoryFactory, mydbcontext) { } public List<User> GetUsers() { var service = this.CreateService<User>(); return service.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依賴注入配置。
public void ConfigureServices(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項目設爲啓動項目,運行看結果。