IOC+EF+Core项目搭建EF封装(一)
添加应用Microsoft.EntityFrameworkCore;Microsoft.EntityFrameworkCore.Design;Microsoft.EntityFrameworkCore.SqlServer
base类
public abstract partial class BaseEntity
{
/// <summary>
/// id
/// </summary>
public Guid gid { get; set; }
}
分装仓储结构接口
/// <summary>
/// 仓储db接口
/// </summary>
public partial interface IDbContext
{
#region 方法
/// <summary>
/// 创建可用于查询和保存实体实例的DbSet
/// </summary>
/// <typeparam name="TEntity">Entity type</typeparam>
/// <returns>A set for the given entity type</returns>
DbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity; /// <summary>
/// 将在此上下文中所做的所有更改保存到数据库
/// </summary>
/// <returns>The number of state entries written to the database</returns>
int SaveChanges(); /// <summary>
/// 生成一个脚本,为当前模型创建所有表
/// </summary>
/// <returns>A SQL script</returns>
string GenerateCreateScript(); /// <summary>
/// 基于原始SQL查询为查询类型创建LINQ查询
/// </summary>
/// <typeparam name="TQuery">Query type</typeparam>
/// <param name="sql">The raw SQL query</param>
/// <returns>An IQueryable representing the raw SQL query</returns>
IQueryable<TQuery> QueryFromSql<TQuery>(string sql) where TQuery : class; /// <summary>
/// 基于原始SQL查询为实体创建LINQ查询
/// </summary>
/// <typeparam name="TEntity">Entity type</typeparam>
/// <param name="sql">The raw SQL query</param>
/// <param name="parameters">The values to be assigned to parameters</param>
/// <returns>An IQueryable representing the raw SQL query</returns>
IQueryable<TEntity> EntityFromSql<TEntity>(string sql, params object[] parameters) where TEntity : BaseEntity; /// <summary>
/// 对数据库执行给定的SQL
/// </summary>
/// <param name="sql">The SQL to execute</param>
/// <param name="doNotEnsureTransaction">true - the transaction creation is not ensured; false - the transaction creation is ensured.</param>
/// <param name="timeout">The timeout to use for command. Note that the command timeout is distinct from the connection timeout, which is commonly set on the database connection string</param>
/// <param name="parameters">Parameters to use with the SQL</param>
/// <returns>The number of rows affected</returns>
int ExecuteSqlCommand(RawSqlString sql, bool doNotEnsureTransaction = false, int? timeout = null, params object[] parameters); /// <summary>
/// 从上下文中分离一个实体
/// </summary>
/// <typeparam name="TEntity">Entity type</typeparam>
/// <param name="entity">Entity</param>
void Detach<TEntity>(TEntity entity) where TEntity : BaseEntity;
#endregion
}
/// <summary>
/// 基础仓储接口
/// </summary>
public partial interface IRepository<TEntity> where TEntity : BaseEntity
{
#region 方法
/// <summary>
/// 查询对象
/// </summary>
TEntity GetById(object gid); /// <summary>
/// 添加
/// </summary>
void Insert(TEntity entity); /// <summary>
/// 批量添加
/// </summary>
void Insert(IEnumerable<TEntity> entities); /// <summary>
/// 修改
/// </summary>
void Update(TEntity entity); /// <summary>
/// 批量修改
/// </summary>
void Update(IEnumerable<TEntity> entities); /// <summary>
/// 删除
/// </summary>
void Delete(TEntity entity); /// <summary>
/// 批量删除
/// </summary>
void Delete(IEnumerable<TEntity> entities);
#endregion #region 属性
/// <summary>
/// 查询数据集
/// </summary>
IQueryable<TEntity> Table { get; } /// <summary>
/// 获取一个启用“no tracking”(EF特性)的表,仅当您仅为只读操作加载记录时才使用它
/// </summary>
IQueryable<TEntity> TableNoTracking { get; }
#endregion
}
/// <summary>
/// 基础仓储实现
/// </summary>
public partial class EfRepository<TEntity> : IRepository<TEntity> where TEntity : BaseEntity
{
#region 参数
private readonly IDbContext _context;
private DbSet<TEntity> _entities;
#endregion #region 构造函数
public EfRepository(IDbContext context)
{
this._context = context;
}
#endregion #region 公共方法
/// <summary>
/// 实体更改的回滚并返回完整的错误消息
/// </summary>
/// <param name="exception">Exception</param>
/// <returns>Error message</returns>
protected string GetFullErrorTextAndRollbackEntityChanges(DbUpdateException exception)
{
//回滚实体
if (_context is DbContext dbContext)
{
var entries = dbContext.ChangeTracker.Entries()
.Where(e => e.State == EntityState.Added || e.State == EntityState.Modified).ToList(); entries.ForEach(entry => entry.State = EntityState.Unchanged);
}
_context.SaveChanges();
return exception.ToString();
}
#endregion #region 方法
/// <summary>
/// 按id获取实体
/// </summary>
/// <param name="id">Identifier</param>
/// <returns>Entity</returns>
public virtual TEntity GetById(object id)
{
return Entities.Find(id);
} /// <summary>
/// 添加
/// </summary>
/// <param name="entity">Entity</param>
public virtual void Insert(TEntity entity)
{
if (entity == null)
throw new ArgumentNullException(nameof(entity)); try
{
Entities.Add(entity);
_context.SaveChanges();
}
catch (DbUpdateException exception)
{
//ensure that the detailed error text is saved in the Log
throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception);
}
} /// <summary>
/// 批量添加
/// </summary>
/// <param name="entities">Entities</param>
public virtual void Insert(IEnumerable<TEntity> entities)
{
if (entities == null)
throw new ArgumentNullException(nameof(entities)); try
{
Entities.AddRange(entities);
_context.SaveChanges();
}
catch (DbUpdateException exception)
{
//ensure that the detailed error text is saved in the Log
throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception);
}
} /// <summary>
/// 修改
/// </summary>
/// <param name="entity">Entity</param>
public virtual void Update(TEntity entity)
{
if (entity == null)
throw new ArgumentNullException(nameof(entity)); try
{
Entities.Update(entity);
_context.SaveChanges();
}
catch (DbUpdateException exception)
{
//ensure that the detailed error text is saved in the Log
throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception);
}
} /// <summary>
/// 批量修改
/// </summary>
/// <param name="entities">Entities</param>
public virtual void Update(IEnumerable<TEntity> entities)
{
if (entities == null)
throw new ArgumentNullException(nameof(entities)); try
{
Entities.UpdateRange(entities);
_context.SaveChanges();
}
catch (DbUpdateException exception)
{
//ensure that the detailed error text is saved in the Log
throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception);
}
} /// <summary>
/// 删除
/// </summary>
/// <param name="entity">Entity</param>
public virtual void Delete(TEntity entity)
{
if (entity == null)
throw new ArgumentNullException(nameof(entity)); try
{
Entities.Remove(entity);
_context.SaveChanges();
}
catch (DbUpdateException exception)
{
//ensure that the detailed error text is saved in the Log
throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception);
}
} /// <summary>
/// 批量删除
/// </summary>
/// <param name="entities">Entities</param>
public virtual void Delete(IEnumerable<TEntity> entities)
{
if (entities == null)
throw new ArgumentNullException(nameof(entities)); try
{
Entities.RemoveRange(entities);
_context.SaveChanges();
}
catch (DbUpdateException exception)
{
//ensure that the detailed error text is saved in the Log
throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception);
}
} #endregion #region 属性
/// <summary>
/// 获取表
/// </summary>
public virtual IQueryable<TEntity> Table => Entities; /// <summary>
/// 获取一个启用“no tracking”(EF特性)的表,仅当您仅为只读操作加载记录时才使用它
/// </summary>
public virtual IQueryable<TEntity> TableNoTracking => Entities.AsNoTracking(); /// <summary>
/// 获取设置模板
/// </summary>
protected virtual DbSet<TEntity> Entities
{
get
{
if (_entities == null)
_entities = _context.Set<TEntity>(); return _entities;
}
}
#endregion
}
ef的模型映射封装
/// <summary>
/// 表示数据库上下文模型映射配置
/// </summary>
public partial interface IMappingConfiguration
{
/// <summary>
/// 应用此映射配置
/// </summary>
/// <param name="modelBuilder">用于构造数据库上下文模型的生成器</param>
void ApplyConfiguration(ModelBuilder modelBuilder);
}
/// <summary>
/// 表示基本实体映射配置
/// </summary>
/// <typeparam name="TEntity">Entity type</typeparam>
public partial class NopEntityTypeConfiguration<TEntity> : IMappingConfiguration, IEntityTypeConfiguration<TEntity> where TEntity : BaseEntity
{
#region Utilities
/// <summary>
/// Developers can override this method in custom partial classes in order to add some custom configuration code
/// </summary>
/// <param name="builder">The builder to be used to configure the entity</param>
protected virtual void PostConfigure(EntityTypeBuilder<TEntity> builder)
{
}
#endregion #region Methods
/// <summary>
/// Configures the entity
/// </summary>
/// <param name="builder">The builder to be used to configure the entity</param>
public virtual void Configure(EntityTypeBuilder<TEntity> builder)
{
//add custom configuration
this.PostConfigure(builder);
} /// <summary>
/// Apply this mapping configuration
/// </summary>
/// <param name="modelBuilder">The builder being used to construct the model for the database context</param>
public virtual void ApplyConfiguration(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfiguration(this);
}
#endregion
}
/// <summary>
/// 表示基本EF对象上下文
/// </summary>
public partial class NopObjectContext : DbContext, IDbContext
{
#region 构造函数
public NopObjectContext(DbContextOptions<NopObjectContext> options) : base(options)
{
}
#endregion #region 公共方法
/// <summary>
/// 进一步配置注册映射模型
/// </summary>
/// <param name="modelBuilder">用于为该上下文构造模型的构造器</param>
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//动态加载所有实体和查询类型配置
var typeConfigurations = Assembly.GetExecutingAssembly().GetTypes().Where(type =>
(type.BaseType?.IsGenericType ?? false)
&& (type.BaseType.GetGenericTypeDefinition() == typeof(NopEntityTypeConfiguration<>))); foreach (var typeConfiguration in typeConfigurations)
{
var configuration = (IMappingConfiguration)Activator.CreateInstance(typeConfiguration);
configuration.ApplyConfiguration(modelBuilder);
} base.OnModelCreating(modelBuilder);
} /// <summary>
/// 通过添加传递的参数来修改输入SQL查询
/// </summary>
/// <param name="sql">The raw SQL query</param>
/// <param name="parameters">The values to be assigned to parameters</param>
/// <returns>Modified raw SQL query</returns>
protected virtual string CreateSqlWithParameters(string sql, params object[] parameters)
{
//add parameters to sql
for (var i = ; i <= (parameters?.Length ?? ) - ; i++)
{
if (!(parameters[i] is DbParameter parameter))
continue; sql = $"{sql}{(i > 0 ? "," : string.Empty)} @{parameter.ParameterName}"; //whether parameter is output
if (parameter.Direction == ParameterDirection.InputOutput || parameter.Direction == ParameterDirection.Output)
sql = $"{sql} output";
} return sql;
}
#endregion #region 方法
/// <summary>
/// 创建可用于查询和保存实体实例的DbSet
/// </summary>
/// <typeparam name="TEntity">Entity type</typeparam>
/// <returns>A set for the given entity type</returns>
public virtual new DbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity
{
return base.Set<TEntity>();
} /// <summary>
/// 生成一个脚本,为当前模型创建所有表
/// </summary>
/// <returns>A SQL script</returns>
public virtual string GenerateCreateScript()
{
return this.Database.GenerateCreateScript();
} /// <summary>
/// 基于原始SQL查询为查询类型创建LINQ查询
/// </summary>
/// <typeparam name="TQuery">Query type</typeparam>
/// <param name="sql">The raw SQL query</param>
/// <returns>An IQueryable representing the raw SQL query</returns>
public virtual IQueryable<TQuery> QueryFromSql<TQuery>(string sql) where TQuery : class
{
return this.Query<TQuery>().FromSql(sql);
} /// <summary>
///基于原始SQL查询为实体创建LINQ查询
/// </summary>
/// <typeparam name="TEntity">Entity type</typeparam>
/// <param name="sql">The raw SQL query</param>
/// <param name="parameters">The values to be assigned to parameters</param>
/// <returns>An IQueryable representing the raw SQL query</returns>
public virtual IQueryable<TEntity> EntityFromSql<TEntity>(string sql, params object[] parameters) where TEntity : BaseEntity
{
return this.Set<TEntity>().FromSql(CreateSqlWithParameters(sql, parameters), parameters);
} /// <summary>
/// 对数据库执行给定的SQL
/// </summary>
/// <param name="sql">The SQL to execute</param>
/// <param name="doNotEnsureTransaction">true - the transaction creation is not ensured; false - the transaction creation is ensured.</param>
/// <param name="timeout">The timeout to use for command. Note that the command timeout is distinct from the connection timeout, which is commonly set on the database connection string</param>
/// <param name="parameters">Parameters to use with the SQL</param>
/// <returns>The number of rows affected</returns>
public virtual int ExecuteSqlCommand(RawSqlString sql, bool doNotEnsureTransaction = false, int? timeout = null, params object[] parameters)
{
//set specific command timeout
var previousTimeout = this.Database.GetCommandTimeout();
this.Database.SetCommandTimeout(timeout); var result = ;
if (!doNotEnsureTransaction)
{
//use with transaction
using (var transaction = this.Database.BeginTransaction())
{
result = this.Database.ExecuteSqlCommand(sql, parameters);
transaction.Commit();
}
}
else
result = this.Database.ExecuteSqlCommand(sql, parameters); //return previous timeout back
this.Database.SetCommandTimeout(previousTimeout); return result;
} /// <summary>
/// 从上下文中分离一个实体
/// </summary>
/// <typeparam name="TEntity">Entity type</typeparam>
/// <param name="entity">Entity</param>
public virtual void Detach<TEntity>(TEntity entity) where TEntity : BaseEntity
{
if (entity == null)
throw new ArgumentNullException(nameof(entity)); var entityEntry = this.Entry(entity);
if (entityEntry == null)
return; //set the entity is not being tracked by the context
entityEntry.State = EntityState.Detached;
}
#endregion
}

代码都是从nop开源项目出抠出来的
IOC+EF+Core项目搭建EF封装(一)的更多相关文章
- IOC+EF+Core项目搭建IOC注入及框架(二)
配置ServiceCollection /// <summary> /// 表示IServiceCollection的扩展 /// </summary> public stat ...
- Asp.net Core + EF Core + Bootstrap搭建的MVC后台通用管理系统模板(跨平台版本)
Asp.net Core + EF Core + Bootstrap搭建的MVC后台通用管理系统模板(跨平台版本) 原创 2016年07月22日 10:33:51 23125 6月随着.NET COR ...
- EF Core 快速上手——EF Core 入门
EF Core 快速上手--EF Core 介绍 本章导航 从本书你能学到什么 对EF6.x 程序员的一些话 EF Core 概述 1.3.1 ORM框架的缺点 第一个EF Core应用 本文是对 ...
- ASP.NET CORE 项目搭建(2022 年 3 月版)
ASP.NET CORE 项目搭建(2022 年 3 月版) 自读 沉淀了多年的技术积累,在 .NET FRAMEWORK 的框架下尝试造过自己的轮子. 摸索着闭门造过 基于 OWIN 服务后端. 摸 ...
- EF Core 快速上手——EF Core的三种主要关系类型
系列文章 EF Core 快速上手--EF Core 入门 本节导航 三种数据库关系类型建模 Migration方式创建和习修改数据库 定义和创建应用DbContext 将复杂查询拆分为子查询 本 ...
- ASP.NET Core MVC+EF Core项目实战
项目背景 本项目参考于<Pro Entity Framework Core 2 for ASP.NET Core MVC>一书,项目内容为party邀请答复. 新建项目 本项目开发工具为V ...
- EF Core 三 、 EF Core CRUD
EF Core CRUD 上篇文章中,我们已经基本入门了EFCore,搭建了一个简单的EFCore项目,本文开始简单使用下EF,做增删改查的相关操作: 一.数据新增操作(C) public stati ...
- 《Asp.Net Core3 + Vue3入坑教程》-Net Core项目搭建与Swagger配置步骤
简介 <Asp.Net Core3 + Vue3入坑教程> 此教程仅适合新手入门或者前后端分离尝试者.可以根据图文一步一步进操作编码也可以选择直接查看源码.每一篇文章都有对应的源码 教程后 ...
- EF Core 迁移过程遇到EF Core tools version版本不相符的解决方案
如果你使用命令: PM> add-migration Inital 提示如下信息时: The EF Core tools version '2.1.1-rtm-30846' is older t ...
随机推荐
- 「PKUSC2018」星际穿越
传送门 Solution 倍增 Code #include <bits/stdc++.h> #define reg register #define ll long long usin ...
- Java 12 骚操作, 文件比对居然还能这样玩!
Java 13 都快要来了,12必须跟栈长学起! Java 13 即将发布,新特性必须抢先看! 之前分享了一些 Java 12 的骚操作,今天继续,今天要分享的是 Java 12 中的文件比对骚操作. ...
- 集合类 collection接口 ArrayList
数组: 存储同一种数据类型的集合容器.数组的特点:1. 只能存储同一种数据类型的数据.2. 一旦初始化,长度固定. 3. 数组中的元素与元素之间的内存地址是连续的. : Object类型的数组可以存储 ...
- 安装关系型数据库MySQL 安装大数据处理框架Hadoop
作业要求来自:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/3161 1.Hadoop的介绍 Hadoop最早起源于Nutch.Nut ...
- [转]CSS3 使用 calc() 计算高度 vh px
1.px 像素,我们在网页布局中一般都是用px. 2.百分比 百分比一般宽泛的讲是相对于父元素,自适应网页布局越来越多,百分比也经常用到了. 3.Viewport viewport:可视窗口,也 ...
- Java JDBC利用反射技术将查询结果封装为对象
1.JDBC将返回结果集封装成对象demo class JdbcDemo { /** * 获取数据库列名 * @param rs * @return */ private static String[ ...
- python爬虫案例:使用XPath爬网页图片
用XPath来做一个简单的爬虫,尝试爬取某个贴吧里的所有帖子,并且将该这个帖子里每个楼层发布的图片下载到本地. # -*- coding:utf-8 -*- import urllib import ...
- openresty开发系列32--openresty执行流程之1初始化阶段
openresty开发系列32--openresty执行流程之初始化阶段 一)初始化阶段 1)init_by_lua init_by_lua_block init_by_lua_file语 ...
- C++11新特性— auto 和 decltype 区别和联系
一. auto简介 编程时候常常需要把表达式的值付给变量,需要在声明变量的时候清楚的知道变量是什么类型.然而做到这一点并非那么容易(特别是模板中),有时候根本做不到.为了解决这个问题,C++11新标准 ...
- Shell中的通配符
shell常见的通配符,注意与正则稍有不同: 字符 含义 实例 * 匹配0个或多个任意字符 a*b,a与b之间可以有任意长度的字符,也可以没有. 例如:aabcb,ab,azxcb... ? 匹配一个 ...