初始提交
This commit is contained in:
119
Infrastructure/Hncore.Infrastructure/EF/DbContextBase.cs
Normal file
119
Infrastructure/Hncore.Infrastructure/EF/DbContextBase.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
using Hncore.Infrastructure.Common;
|
||||
using Hncore.Infrastructure.DDD;
|
||||
using Hncore.Infrastructure.Extension;
|
||||
using Hncore.Infrastructure.Serializer;
|
||||
using Hncore.Infrastructure.WebApi;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
namespace Hncore.Infrastructure.EF
|
||||
{
|
||||
/// <summary>
|
||||
/// 上下文构造器的基类
|
||||
/// </summary>
|
||||
public class DbContextBase : DbContext
|
||||
{
|
||||
private IHttpContextAccessor _httpContextAccessor;
|
||||
|
||||
private bool _enabledLog = false;
|
||||
|
||||
private int _tenantid = 0;
|
||||
|
||||
private int _storeId = 0;
|
||||
|
||||
private bool _root = false;
|
||||
|
||||
private bool _allow = false;
|
||||
|
||||
public DbContextBase(DbContextOptions options, IHttpContextAccessor httpContextAccessor) : base(options)
|
||||
{
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
|
||||
if (UseTenantFilter())
|
||||
{
|
||||
ManageUserInfo manageUserInfo = _httpContextAccessor.HttpContext.Request.GetManageUserInfo();
|
||||
|
||||
if (manageUserInfo != null)
|
||||
{
|
||||
_tenantid = manageUserInfo.TenantId;
|
||||
_storeId = manageUserInfo.StoreId;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_allow = true;
|
||||
}
|
||||
}
|
||||
|
||||
private bool UseTenantFilter()
|
||||
{
|
||||
if (_httpContextAccessor == null || _httpContextAccessor.HttpContext == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return _httpContextAccessor.HttpContext.Items.ContainsKey("AuthPassedFilterName")
|
||||
&& _httpContextAccessor.HttpContext.Items["AuthPassedFilterName"].ToString() == "ManageAuth";
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// model构造器 创建实体映射
|
||||
/// </summary>
|
||||
/// <param name="modelBuilder"></param>
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
|
||||
if (!EnvironmentVariableHelper.IsAspNetCoreProduction)
|
||||
{
|
||||
LogHelper.Debug("进入DbContextBase的OnModelCreating函数",
|
||||
$"UseGlobalManageAuthFilter:{GlobalData.UseGlobalManageAuthFilter}\ntoken:{_httpContextAccessor?.HttpContext?.Request?.GetManageUserInfo()?.ToJson(true)}");
|
||||
}
|
||||
|
||||
foreach (var type in modelBuilder.Model.GetEntityTypes())
|
||||
{
|
||||
if (typeof(ISoftDelete).IsAssignableFrom(type.ClrType))
|
||||
{
|
||||
modelBuilder.Entity(type.ClrType).AddQueryFilter<ISoftDelete>(t => t.DeleteTag == 0);
|
||||
}
|
||||
//if (typeof(ITenant).IsAssignableFrom(type.ClrType))
|
||||
//{
|
||||
// modelBuilder.Entity(type.ClrType).AddQueryFilter<ITenant>(t => _allow || t.TenantId == _tenantid);
|
||||
//}
|
||||
|
||||
//if (typeof(ITenantStore).IsAssignableFrom(type.ClrType))
|
||||
//{
|
||||
// modelBuilder.Entity(type.ClrType)
|
||||
// .AddQueryFilter<ITenantStore>(t => _storeId == 0|| t.StoreId==_storeId);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
if (_httpContextAccessor?.HttpContext?.Request?.Headers != null)
|
||||
{
|
||||
if (_httpContextAccessor.HttpContext.Request.Headers.ContainsKey("enable-ef-log"))
|
||||
{
|
||||
if (_httpContextAccessor.HttpContext.Request.Headers.ContainsKey("enable-ef-log").ToBool())
|
||||
{
|
||||
if (_enabledLog == false)
|
||||
{
|
||||
optionsBuilder.EnableDebugTrace(_httpContextAccessor);
|
||||
_enabledLog = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#if DEBUG
|
||||
Console.WriteLine("当前为debug模式,开启EF DebugTrace");
|
||||
optionsBuilder.EnableDebugTrace(null);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
228
Infrastructure/Hncore.Infrastructure/EF/DbContextExtension.cs
Normal file
228
Infrastructure/Hncore.Infrastructure/EF/DbContextExtension.cs
Normal file
@@ -0,0 +1,228 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Hncore.Infrastructure.Extension
|
||||
{
|
||||
/// <summary>
|
||||
/// EF上下文对象扩展类
|
||||
/// </summary>
|
||||
///
|
||||
public static class DbContextExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 执行SQL返回受影响的行数
|
||||
/// </summary>
|
||||
public static int ExecSqlNoQuery(this DbContext db, string sql, DbParameter[] sqlParams = null)
|
||||
{
|
||||
return ExecuteNoQuery(db, sql, sqlParams);
|
||||
}
|
||||
/// <summary>
|
||||
/// 执行存储过程返回IEnumerable数据集
|
||||
/// </summary>
|
||||
public static IEnumerable<T> ExecProcQuery<T>(this DbContext db, string sql, DbParameter[] sqlParams = null) where T : new()
|
||||
{
|
||||
return Execute<T>(db, sql, CommandType.StoredProcedure, sqlParams);
|
||||
}
|
||||
/// <summary>
|
||||
/// 执行存储过程返回IEnumerable数据集
|
||||
/// </summary>
|
||||
public static DataSet ExecProcDataSet(this DbContext db, string sql, DbParameter[] sqlParams = null)
|
||||
{
|
||||
return ExecuteDataSet(db, sql, CommandType.StoredProcedure, sqlParams);
|
||||
}
|
||||
/// <summary>
|
||||
/// 执行sql返回IEnumerable数据集
|
||||
/// </summary>
|
||||
public static IEnumerable<T> ExecSqlQuery<T>(this DbContext db, string sql, DbParameter[] sqlParams = null) where T : new()
|
||||
{
|
||||
return Execute<T>(db, sql, CommandType.Text, sqlParams);
|
||||
}
|
||||
/// <summary>
|
||||
/// 执行SQL并返回受影响的行数
|
||||
/// </summary>
|
||||
/// <param name="db"></param>
|
||||
/// <param name="sql"></param>
|
||||
/// <param name="sqlParams"></param>
|
||||
/// <returns></returns>
|
||||
private static int ExecuteNoQuery(this DbContext db, string sql, DbParameter[] sqlParams)
|
||||
{
|
||||
DbConnection connection = db.Database.GetDbConnection();
|
||||
DbCommand cmd = connection.CreateCommand();
|
||||
int result = 0;
|
||||
db.Database.OpenConnection();
|
||||
cmd.CommandText = sql;
|
||||
cmd.CommandType = CommandType.Text;
|
||||
if (sqlParams != null)
|
||||
{
|
||||
cmd.Parameters.AddRange(sqlParams);
|
||||
}
|
||||
result = cmd.ExecuteNonQuery();
|
||||
db.Database.CloseConnection();
|
||||
return result;
|
||||
}
|
||||
/// <summary>
|
||||
/// 执行SQL,返回查询结果
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="db"></param>
|
||||
/// <param name="sql"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="sqlParams"></param>
|
||||
/// <returns></returns>
|
||||
private static IEnumerable<T> Execute<T>(this DbContext db, string sql, CommandType type, DbParameter[] sqlParams) where T : new()
|
||||
{
|
||||
DbConnection connection = db.Database.GetDbConnection();
|
||||
DbCommand cmd = connection.CreateCommand();
|
||||
DataTable dt = new DataTable();
|
||||
try
|
||||
{
|
||||
db.Database.OpenConnection();
|
||||
cmd.CommandText = sql;
|
||||
cmd.CommandType = type;
|
||||
if (sqlParams != null)
|
||||
{
|
||||
cmd.Parameters.AddRange(sqlParams);
|
||||
}
|
||||
using (DbDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
dt.Load(reader);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
db.Database.CloseConnection();
|
||||
}
|
||||
return dt.ToCollection<T>();
|
||||
}
|
||||
/// <summary>
|
||||
/// 执行SQL,返回查询结果
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="db"></param>
|
||||
/// <param name="sql"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="sqlParams"></param>
|
||||
/// <returns></returns>
|
||||
private static DataSet ExecuteDataSet(this DbContext db, string sql, CommandType type, DbParameter[] sqlParams)
|
||||
{
|
||||
DbConnection connection = db.Database.GetDbConnection();
|
||||
DbCommand cmd = connection.CreateCommand();
|
||||
db.Database.OpenConnection();
|
||||
cmd.CommandText = sql;
|
||||
cmd.CommandType = type;
|
||||
if (sqlParams != null)
|
||||
{
|
||||
cmd.Parameters.AddRange(sqlParams);
|
||||
}
|
||||
DataSet ds = new DataSet();
|
||||
using (DbDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
ds.Load(reader,LoadOption.PreserveChanges,"data","info");
|
||||
}
|
||||
db.Database.CloseConnection();
|
||||
return ds;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DataTable扩展类
|
||||
/// </summary>
|
||||
///
|
||||
public static class ExtendDataTable
|
||||
{
|
||||
/// <summary>
|
||||
/// 将对象转换成DataTable
|
||||
/// </summary>
|
||||
/// <typeparam name="T">源对象类型</typeparam>
|
||||
/// <param name="data">源对象列表</param>
|
||||
/// <returns>转换后的DataTable</returns>
|
||||
///
|
||||
public static DataTable ToDataTable<T>(this IEnumerable<T> data)
|
||||
{
|
||||
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
|
||||
var table = new DataTable();
|
||||
foreach (PropertyDescriptor prop in properties)
|
||||
table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
|
||||
foreach (T item in data)
|
||||
{
|
||||
DataRow row = table.NewRow();
|
||||
foreach (PropertyDescriptor prop in properties)
|
||||
row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
|
||||
table.Rows.Add(row);
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将DataTable首行转换成目标对象
|
||||
/// </summary>
|
||||
/// <typeparam name="T">目标对象类型</typeparam>
|
||||
/// <param name="dt">源DataTable对象</param>
|
||||
/// <returns>转换后的目标对象</returns>
|
||||
///
|
||||
public static T ToEntity<T>(this DataTable dt) where T : new()
|
||||
{
|
||||
IEnumerable<T> entities = dt.ToCollection<T>();
|
||||
return entities.FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将DataTable转换成目标对象列表
|
||||
/// </summary>
|
||||
/// <typeparam name="T">目标对象类型</typeparam>
|
||||
/// <param name="dt">源DataTable对象</param>
|
||||
/// <returns>转换后的目标对象列表</returns>
|
||||
///
|
||||
public static IEnumerable<T> ToCollection<T>(this DataTable dt) where T : new()
|
||||
{
|
||||
if (dt == null || dt.Rows.Count == 0)
|
||||
{
|
||||
return Enumerable.Empty<T>();
|
||||
}
|
||||
IList<T> ts = new List<T>();
|
||||
// 获得此模型的类型
|
||||
Type type = typeof(T);
|
||||
string tempName = string.Empty;
|
||||
foreach (DataRow dr in dt.Rows)
|
||||
{
|
||||
T t = new T();
|
||||
PropertyInfo[] propertys = t.GetType().GetProperties();
|
||||
foreach (PropertyInfo pi in propertys)
|
||||
{
|
||||
tempName = pi.Name;
|
||||
//检查DataTable是否包含此列(列名==对象的属性名)
|
||||
if (dt.Columns.Contains(tempName))
|
||||
{
|
||||
// 判断此属性是否有Setter
|
||||
if (!pi.CanWrite) continue;//该属性不可写,直接跳出
|
||||
object value = dr[tempName];
|
||||
if (value != DBNull.Value)
|
||||
{
|
||||
if (!pi.PropertyType.IsGenericType)
|
||||
{
|
||||
value = Convert.ChangeType(value, pi.PropertyType);
|
||||
pi.SetValue(t, value);
|
||||
}
|
||||
else {
|
||||
Type genericTypeDefinition = pi.PropertyType.GetGenericTypeDefinition();
|
||||
if (genericTypeDefinition == typeof(Nullable<>))
|
||||
{
|
||||
value = Convert.ChangeType(value, Nullable.GetUnderlyingType(pi.PropertyType));
|
||||
pi.SetValue(t, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ts.Add(t);
|
||||
}
|
||||
return ts;
|
||||
}
|
||||
}
|
||||
}
|
||||
122
Infrastructure/Hncore.Infrastructure/EF/DbSetExtension.cs
Normal file
122
Infrastructure/Hncore.Infrastructure/EF/DbSetExtension.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Hncore.Infrastructure.Data;
|
||||
using Hncore.Infrastructure.DDD;
|
||||
using Hncore.Infrastructure.EntitiesExtension;
|
||||
|
||||
namespace Hncore.Infrastructure.EF
|
||||
{
|
||||
public static class DbSetExtension
|
||||
{
|
||||
public static TEntity GetOne<TEntity>(this DbSet<TEntity> dbSet, Expression<Func<TEntity, bool>> exp)
|
||||
where TEntity : class
|
||||
{
|
||||
return dbSet.AsNoTracking().FirstOrDefault(exp);
|
||||
}
|
||||
|
||||
public static Task<TEntity> GetOneAsync<TEntity>(this DbSet<TEntity> dbSet,
|
||||
Expression<Func<TEntity, bool>> exp) where TEntity : class
|
||||
{
|
||||
return dbSet.AsNoTracking().FirstOrDefaultAsync(exp);
|
||||
}
|
||||
|
||||
public static PageData<TEntity> GetList<TEntity, TId>(this DbSet<TEntity> dbSet,
|
||||
Expression<Func<TEntity, bool>> exp, int pagesize, int pageindex, bool istotal)
|
||||
where TEntity : class, IEntity<TId>
|
||||
{
|
||||
return dbSet.AsNoTracking()
|
||||
.Where(exp)
|
||||
.OrderByDescending(t => t.Id)
|
||||
.ListPager(pagesize, pageindex, istotal);
|
||||
}
|
||||
|
||||
public static Task<PageData<TEntity>> GetListAsync<TEntity>(this DbSet<TEntity> dbSet,
|
||||
Expression<Func<TEntity, bool>> exp, int pagesize, int pageindex, bool istotal)
|
||||
where TEntity : class
|
||||
{
|
||||
return dbSet.AsNoTracking()
|
||||
.Where(exp)
|
||||
.ListPagerAsync(pagesize, pageindex, istotal);
|
||||
}
|
||||
|
||||
public static List<TEntity> GetList<TEntity>(this DbSet<TEntity> dbSet, Expression<Func<TEntity, bool>> exp)
|
||||
where TEntity : class, IEntity
|
||||
{
|
||||
return dbSet.AsNoTracking()
|
||||
.Where(exp)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public static Task<List<TEntity>> GetListAsync<TEntity>(this DbSet<TEntity> dbSet,
|
||||
Expression<Func<TEntity, bool>> exp)
|
||||
where TEntity : class, IEntity
|
||||
{
|
||||
return dbSet.AsNoTracking()
|
||||
.Where(exp)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public static IQueryable<TEntity> GetListQueryable<TEntity>(this DbSet<TEntity> dbSet,
|
||||
Expression<Func<TEntity, bool>> exp)
|
||||
where TEntity : class, IEntity
|
||||
{
|
||||
return dbSet.AsNoTracking()
|
||||
.Where(exp);
|
||||
}
|
||||
|
||||
public static bool Exists<TEntity>(this DbSet<TEntity> dbSet, Expression<Func<TEntity, bool>> exp)
|
||||
where TEntity : class, IEntity
|
||||
{
|
||||
return dbSet.AsNoTracking()
|
||||
.Any(exp);
|
||||
}
|
||||
|
||||
public static Task<bool> ExistsAsync<TEntity>(this DbSet<TEntity> dbSet,
|
||||
Expression<Func<TEntity, bool>> exp)
|
||||
where TEntity : class, IEntity
|
||||
{
|
||||
return dbSet.AsNoTracking()
|
||||
.AnyAsync(exp);
|
||||
}
|
||||
|
||||
public static List<TEntity> TopN<TEntity>(this DbSet<TEntity> dbSet,
|
||||
Expression<Func<TEntity, bool>> condition, int topN)
|
||||
where TEntity : class, IEntity
|
||||
{
|
||||
return dbSet.AsNoTracking()
|
||||
.Where(condition)
|
||||
.TopN(topN)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public static Task<List<TEntity>> TopNAsync<TEntity>(this DbSet<TEntity> dbSet,
|
||||
Expression<Func<TEntity, bool>> condition, int topN)
|
||||
where TEntity : class, IEntity
|
||||
{
|
||||
return dbSet.AsNoTracking()
|
||||
.Where(condition)
|
||||
.TopN(topN)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public static IQueryable<TEntity> GetQueryable<TEntity>(this DbSet<TEntity> dbSet) where TEntity : class
|
||||
{
|
||||
return dbSet.AsNoTracking();
|
||||
}
|
||||
|
||||
public static TEntity FindById<TEntity>(this DbSet<TEntity> dbSet,object id) where TEntity : class
|
||||
{
|
||||
return dbSet.Find(id);
|
||||
}
|
||||
|
||||
public static Task<TEntity> FindByIdAsync<TEntity>(this DbSet<TEntity> dbSet, object id) where TEntity : class
|
||||
{
|
||||
return dbSet.FindAsync(id);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
25
Infrastructure/Hncore.Infrastructure/EF/EntityMapBase.cs
Normal file
25
Infrastructure/Hncore.Infrastructure/EF/EntityMapBase.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Hncore.Infrastructure.EF
|
||||
{
|
||||
public interface IEntityMap
|
||||
{
|
||||
void Map(ModelBuilder builder);
|
||||
}
|
||||
|
||||
public interface IEntityMap<TEntityType> : IEntityMap where TEntityType : class
|
||||
{
|
||||
void Map(EntityTypeBuilder<TEntityType> builder);
|
||||
}
|
||||
|
||||
public abstract class EntityMapBase<T> : IEntityMap<T> where T : class
|
||||
{
|
||||
public abstract void Map(EntityTypeBuilder<T> builder);
|
||||
|
||||
public void Map(ModelBuilder builder)
|
||||
{
|
||||
Map(builder.Entity<T>());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Hncore.Infrastructure.EF
|
||||
{
|
||||
public static class AutoMapExtensions
|
||||
{
|
||||
private static object syncRoot = new object();
|
||||
private static ConcurrentDictionary<IEntityMap, object> maps;
|
||||
|
||||
public static void AutoMap(this ModelBuilder modelBuilder, Type assType)
|
||||
{
|
||||
if (maps == null)
|
||||
{
|
||||
lock (syncRoot)
|
||||
{
|
||||
if (maps == null)
|
||||
{
|
||||
maps = new ConcurrentDictionary<IEntityMap, object>();
|
||||
|
||||
Type mappingInterface = typeof(IEntityMap<>);
|
||||
|
||||
var mappingTypes = assType.GetTypeInfo().Assembly.GetTypes()
|
||||
.Where(x => !x.IsAbstract
|
||||
&& x.GetInterfaces().Any(y => y.GetTypeInfo().IsGenericType
|
||||
&& y.GetGenericTypeDefinition() ==
|
||||
mappingInterface));
|
||||
|
||||
foreach (var map in mappingTypes.Select(Activator.CreateInstance).Cast<IEntityMap>())
|
||||
{
|
||||
maps.TryAdd(map, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var map in maps.Keys)
|
||||
{
|
||||
map.Map(modelBuilder);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
121
Infrastructure/Hncore.Infrastructure/EF/Extensions/DebugLog.cs
Normal file
121
Infrastructure/Hncore.Infrastructure/EF/Extensions/DebugLog.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Hncore.Infrastructure.Common;
|
||||
using Hncore.Infrastructure.Extension;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Hncore.Infrastructure.Core.Web;
|
||||
|
||||
namespace Hncore.Infrastructure.EF
|
||||
{
|
||||
public class TraceLogger : ILogger
|
||||
{
|
||||
private readonly string categoryName;
|
||||
private IHttpContextAccessor _httpContextAccessor;
|
||||
|
||||
public TraceLogger(string categoryName, IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
this.categoryName = categoryName;
|
||||
this._httpContextAccessor = httpContextAccessor;
|
||||
}
|
||||
|
||||
public bool IsEnabled(LogLevel logLevel) => true;
|
||||
|
||||
public void Log<TState>(
|
||||
LogLevel logLevel,
|
||||
EventId eventId,
|
||||
TState state,
|
||||
Exception exception,
|
||||
Func<TState, Exception, string> formatter)
|
||||
{
|
||||
if (logLevel == LogLevel.Information && categoryName == "Microsoft.EntityFrameworkCore.Database.Command")
|
||||
{
|
||||
Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 执行sql:");
|
||||
|
||||
if (exception != null)
|
||||
{
|
||||
Console.WriteLine("发生异常:\n" + exception);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state.GetType().Name == "LogValues`6")
|
||||
{
|
||||
var paramText = state.GetType().GetField("_value1").GetValue(state).ToString();
|
||||
var sql = state.GetType().GetField("_value5").GetValue(state).ToString();
|
||||
|
||||
var paramList = paramText.RegexMatches("@__.*?='.*?'");
|
||||
|
||||
paramList.ForEach(param =>
|
||||
{
|
||||
var arr = param.Split('=');
|
||||
|
||||
sql = sql.Replace(arr[0], arr[1]);
|
||||
});
|
||||
|
||||
Console.WriteLine(sql);
|
||||
|
||||
if (_httpContextAccessor?.HttpContext?.Request?.Headers != null
|
||||
&& _httpContextAccessor.HttpContext.Request.Headers
|
||||
.ContainsKey("enable-ef-log").ToBool())
|
||||
{
|
||||
StringBuilder log = new StringBuilder();
|
||||
|
||||
log.Append("请求URL:" + _httpContextAccessor.HttpContext.Request.GetAbsoluteUri() + "");
|
||||
log.Append("\nMethod:" + _httpContextAccessor.HttpContext.Request.Method + "\n");
|
||||
if (_httpContextAccessor.HttpContext.Request.Method.ToLower() != "get")
|
||||
{
|
||||
log.Append("Body:\n" + _httpContextAccessor.HttpContext.Items["___requestbody"] +
|
||||
"\n------------------------\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
log.Append("\n------------------------\n");
|
||||
}
|
||||
|
||||
log.Append(sql);
|
||||
|
||||
LogHelper.Debug("efcore日志", log.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} {logLevel} {eventId.Id} {this.categoryName}");
|
||||
//Console.WriteLine(formatter(state, exception));
|
||||
}
|
||||
}
|
||||
|
||||
public IDisposable BeginScope<TState>(TState state) => null;
|
||||
}
|
||||
|
||||
public class TraceLoggerProvider : ILoggerProvider
|
||||
{
|
||||
private IHttpContextAccessor _httpContextAccessor;
|
||||
|
||||
public TraceLoggerProvider(IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
}
|
||||
|
||||
public ILogger CreateLogger(string categoryName) => new TraceLogger(categoryName, _httpContextAccessor);
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class DebugLog
|
||||
{
|
||||
public static void EnableDebugTrace(this DbContextOptionsBuilder optionsBuilder,
|
||||
IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
LoggerFactory loggerFactory = new LoggerFactory();
|
||||
loggerFactory.AddProvider(new TraceLoggerProvider(httpContextAccessor));
|
||||
optionsBuilder.UseLoggerFactory(loggerFactory);
|
||||
optionsBuilder.EnableSensitiveDataLogging();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using Hncore.Infrastructure.Common;
|
||||
using Hncore.Infrastructure.Data;
|
||||
using Hncore.Infrastructure.DDD;
|
||||
using Hncore.Infrastructure.Serializer;
|
||||
using Hncore.Infrastructure.WebApi;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||
using Remotion.Linq.Parsing.ExpressionVisitors;
|
||||
using Hncore.Infrastructure.Core.Web;
|
||||
|
||||
namespace Hncore.Infrastructure.EF
|
||||
{
|
||||
public static class QueryFilterExtensions
|
||||
{
|
||||
public static void AddQueryFilter<T>(this EntityTypeBuilder entityTypeBuilder,
|
||||
Expression<Func<T, bool>> expression)
|
||||
{
|
||||
var parameterType = Expression.Parameter(entityTypeBuilder.Metadata.ClrType);
|
||||
var expressionFilter = ReplacingExpressionVisitor.Replace(
|
||||
expression.Parameters.Single(), parameterType, expression.Body);
|
||||
|
||||
var internalEntityTypeBuilder = entityTypeBuilder.GetInternalEntityTypeBuilder();
|
||||
if (internalEntityTypeBuilder.Metadata.QueryFilter != null)
|
||||
{
|
||||
var currentQueryFilter = internalEntityTypeBuilder.Metadata.QueryFilter;
|
||||
var currentExpressionFilter = ReplacingExpressionVisitor.Replace(
|
||||
currentQueryFilter.Parameters.Single(), parameterType, currentQueryFilter.Body);
|
||||
expressionFilter = Expression.AndAlso(currentExpressionFilter, expressionFilter);
|
||||
}
|
||||
|
||||
var lambdaExpression = Expression.Lambda(expressionFilter, parameterType);
|
||||
entityTypeBuilder.HasQueryFilter(lambdaExpression);
|
||||
}
|
||||
|
||||
internal static InternalEntityTypeBuilder GetInternalEntityTypeBuilder(this EntityTypeBuilder entityTypeBuilder)
|
||||
{
|
||||
var internalEntityTypeBuilder = typeof(EntityTypeBuilder)
|
||||
.GetProperty("Builder", BindingFlags.NonPublic | BindingFlags.Instance)?
|
||||
.GetValue(entityTypeBuilder) as InternalEntityTypeBuilder;
|
||||
|
||||
return internalEntityTypeBuilder;
|
||||
}
|
||||
}
|
||||
}
|
||||
196
Infrastructure/Hncore.Infrastructure/EF/Extensions/Sql.cs
Normal file
196
Infrastructure/Hncore.Infrastructure/EF/Extensions/Sql.cs
Normal file
@@ -0,0 +1,196 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Reflection;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Hncore.Infrastructure.EF
|
||||
{
|
||||
public static class Sql
|
||||
{
|
||||
/// <summary>
|
||||
/// 执行Reader
|
||||
/// </summary>
|
||||
/// <param name="dbContext"></param>
|
||||
/// <param name="sql"></param>
|
||||
/// <param name="action"></param>
|
||||
public static void Reader(this DbContext dbContext, string sql, Action<DbDataReader> action)
|
||||
{
|
||||
var conn = dbContext.Database.GetDbConnection();
|
||||
|
||||
try
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (var command = conn.CreateCommand())
|
||||
{
|
||||
string query = sql;
|
||||
|
||||
command.CommandText = query;
|
||||
|
||||
using (DbDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
if (reader.HasRows)
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
action(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
conn.Close();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行Query
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="dbContext"></param>
|
||||
/// <param name="sql"></param>
|
||||
/// <returns></returns>
|
||||
public static List<T> SqlQuery<T>(this DbContext dbContext, string sql)
|
||||
{
|
||||
List<T> list = new List<T>();
|
||||
|
||||
var conn = dbContext.Database.GetDbConnection();
|
||||
|
||||
try
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (var command = conn.CreateCommand())
|
||||
{
|
||||
string query = sql;
|
||||
|
||||
command.CommandText = query;
|
||||
|
||||
using (DbDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
if (reader.HasRows)
|
||||
{
|
||||
list = reader.ReaderToList<T>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
conn.Close();
|
||||
}
|
||||
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行Sql命令
|
||||
/// </summary>
|
||||
/// <param name="dbContext"></param>
|
||||
/// <param name="sql"></param>
|
||||
/// <returns></returns>
|
||||
public static int ExecuteSql(this DbContext dbContext, string sql)
|
||||
{
|
||||
var conn = dbContext.Database.GetDbConnection();
|
||||
int rowAffected = 0;
|
||||
try
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (var command = conn.CreateCommand())
|
||||
{
|
||||
command.CommandText = sql;
|
||||
rowAffected = command.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
conn.Close();
|
||||
}
|
||||
|
||||
return rowAffected;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DataReader转泛型
|
||||
/// </summary>
|
||||
/// <typeparam name="T">传入的实体类</typeparam>
|
||||
/// <param name="objReader">DataReader对象</param>
|
||||
/// <returns></returns>
|
||||
public static List<T> ReaderToList<T>(this DbDataReader objReader)
|
||||
{
|
||||
using (objReader)
|
||||
{
|
||||
List<T> list = new List<T>();
|
||||
|
||||
//获取传入的数据类型
|
||||
Type modelType = typeof(T);
|
||||
|
||||
//遍历DataReader对象
|
||||
while (objReader.Read())
|
||||
{
|
||||
//使用与指定参数匹配最高的构造函数,来创建指定类型的实例
|
||||
T model = Activator.CreateInstance<T>();
|
||||
for (int i = 0; i < objReader.FieldCount; i++)
|
||||
{
|
||||
//判断字段值是否为空或不存在的值
|
||||
if (!IsNullOrDBNull(objReader[i]))
|
||||
{
|
||||
//匹配字段名
|
||||
PropertyInfo pi = modelType.GetProperty(objReader.GetName(i),
|
||||
BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance |
|
||||
BindingFlags.IgnoreCase);
|
||||
if (pi != null)
|
||||
{
|
||||
//绑定实体对象中同名的字段
|
||||
pi.SetValue(model, CheckType(objReader[i], pi.PropertyType), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list.Add(model);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断指定对象是否是有效值
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
/// <returns></returns>
|
||||
private static bool IsNullOrDBNull(object obj)
|
||||
{
|
||||
return (obj == null || (obj is DBNull)) ? true : false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 对可空类型进行判断转换
|
||||
/// </summary>
|
||||
/// <param name="value">DataReader字段的值</param>
|
||||
/// <param name="conversionType">该字段的类型</param>
|
||||
/// <returns></returns>
|
||||
private static object CheckType(object value, Type conversionType)
|
||||
{
|
||||
if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
|
||||
{
|
||||
if (value == null)
|
||||
return null;
|
||||
System.ComponentModel.NullableConverter nullableConverter =
|
||||
new System.ComponentModel.NullableConverter(conversionType);
|
||||
conversionType = nullableConverter.UnderlyingType;
|
||||
}
|
||||
|
||||
if (typeof(System.Enum).IsAssignableFrom(conversionType))
|
||||
{
|
||||
return Enum.Parse(conversionType, value.ToString());
|
||||
}
|
||||
return Convert.ChangeType(value, conversionType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Hncore.Infrastructure.EF
|
||||
{
|
||||
public interface IQueryDbContext
|
||||
{
|
||||
DbContext DbContext { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Hncore.Infrastructure.EF
|
||||
{
|
||||
public interface IRepositoryDbContext
|
||||
{
|
||||
DbContext DbContext { get; }
|
||||
}
|
||||
}
|
||||
90
Infrastructure/Hncore.Infrastructure/EF/QueryBase.cs
Normal file
90
Infrastructure/Hncore.Infrastructure/EF/QueryBase.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Hncore.Infrastructure.Data;
|
||||
using Hncore.Infrastructure.DDD;
|
||||
|
||||
|
||||
namespace Hncore.Infrastructure.EF
|
||||
{
|
||||
public class QueryBase<TEntity, TId> : IQuery<TEntity, TId> where TEntity : class, IEntity<TId>
|
||||
{
|
||||
protected DbContext Dbcontext;
|
||||
|
||||
public QueryBase(IQueryDbContext dbContext)
|
||||
{
|
||||
Dbcontext = dbContext.DbContext;
|
||||
}
|
||||
|
||||
public TEntity GetOne(Expression<Func<TEntity, bool>> condition)
|
||||
{
|
||||
return Dbcontext.GetOne<TEntity, TId>(condition);
|
||||
}
|
||||
|
||||
public Task<TEntity> GetOneAsync(Expression<Func<TEntity, bool>> condition)
|
||||
{
|
||||
return Dbcontext.GetOneAsync<TEntity, TId>(condition);
|
||||
}
|
||||
|
||||
public PageData<TEntity> GetList(Expression<Func<TEntity, bool>> condition, int pagesize, int pageindex,
|
||||
bool istotal)
|
||||
{
|
||||
return Dbcontext.GetList<TEntity, TId>(condition, pagesize, pageindex, istotal);
|
||||
}
|
||||
|
||||
public Task<PageData<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> condition, int pagesize,
|
||||
int pageindex, bool istotal)
|
||||
{
|
||||
return Dbcontext.GetListAsync<TEntity, TId>(condition, pagesize, pageindex, istotal);
|
||||
}
|
||||
|
||||
public List<TEntity> GetList(Expression<Func<TEntity, bool>> condition)
|
||||
{
|
||||
return Dbcontext.GetList<TEntity, TId>(condition);
|
||||
}
|
||||
|
||||
public Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> condition)
|
||||
{
|
||||
return Dbcontext.GetListAsync<TEntity, TId>(condition);
|
||||
}
|
||||
|
||||
public List<TEntity> TopN(Expression<Func<TEntity, bool>> condition, int topN)
|
||||
{
|
||||
return Dbcontext.TopN<TEntity, TId>(condition, topN);
|
||||
}
|
||||
|
||||
public Task<List<TEntity>> TopNAsync(Expression<Func<TEntity, bool>> condition, int topN)
|
||||
{
|
||||
return Dbcontext.TopNAsync<TEntity, TId>(condition, topN);
|
||||
}
|
||||
|
||||
public IQueryable<TEntity> GetListQueryable(Expression<Func<TEntity, bool>> exp)
|
||||
{
|
||||
return Dbcontext.GetListQueryable<TEntity, TId>(exp);
|
||||
}
|
||||
|
||||
public bool Exists(Expression<Func<TEntity, bool>> exp)
|
||||
{
|
||||
return Dbcontext.Exists<TEntity, TId>(exp);
|
||||
}
|
||||
|
||||
public Task<bool> ExistsAsync(Expression<Func<TEntity, bool>> condition)
|
||||
{
|
||||
return Dbcontext.ExistsAsync<TEntity, TId>(condition);
|
||||
}
|
||||
|
||||
public IQueryable<TEntity> GetQueryable()
|
||||
{
|
||||
return Dbcontext.Set<TEntity>().AsNoTracking();
|
||||
}
|
||||
public DbContext DbContext()
|
||||
{
|
||||
return Dbcontext;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
110
Infrastructure/Hncore.Infrastructure/EF/QueryExtension.cs
Normal file
110
Infrastructure/Hncore.Infrastructure/EF/QueryExtension.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Hncore.Infrastructure.Data;
|
||||
using Hncore.Infrastructure.DDD;
|
||||
using Hncore.Infrastructure.EntitiesExtension;
|
||||
|
||||
namespace Hncore.Infrastructure.EF
|
||||
{
|
||||
public static class QueryExtension
|
||||
{
|
||||
public static TEntity GetOne<TEntity, TId>(this DbContext dbcontext, Expression<Func<TEntity, bool>> exp)
|
||||
where TEntity : class, IEntity<TId>
|
||||
{
|
||||
return dbcontext.Set<TEntity>().AsNoTracking()
|
||||
.FirstOrDefault(exp);
|
||||
}
|
||||
|
||||
public static Task<TEntity> GetOneAsync<TEntity, TId>(this DbContext dbcontext,
|
||||
Expression<Func<TEntity, bool>> exp) where TEntity : class, IEntity<TId>
|
||||
{
|
||||
return dbcontext.Set<TEntity>().AsNoTracking()
|
||||
.FirstOrDefaultAsync(exp);
|
||||
}
|
||||
|
||||
public static PageData<TEntity> GetList<TEntity, TId>(this DbContext dbcontext,
|
||||
Expression<Func<TEntity, bool>> exp, int pagesize, int pageindex, bool istotal)
|
||||
where TEntity : class, IEntity<TId>
|
||||
{
|
||||
return dbcontext.Set<TEntity>().AsNoTracking()
|
||||
.Where(exp)
|
||||
.OrderByDescending(t => t.Id)
|
||||
.ListPager(pagesize, pageindex, istotal);
|
||||
}
|
||||
|
||||
public static Task<PageData<TEntity>> GetListAsync<TEntity, TId>(this DbContext dbcontext,
|
||||
Expression<Func<TEntity, bool>> exp, int pagesize, int pageindex, bool istotal)
|
||||
where TEntity : class, IEntity<TId>
|
||||
{
|
||||
return dbcontext.Set<TEntity>().AsNoTracking()
|
||||
.Where(exp)
|
||||
.OrderByDescending(t => t.Id)
|
||||
.ListPagerAsync(pagesize, pageindex, istotal);
|
||||
}
|
||||
|
||||
public static List<TEntity> GetList<TEntity, TId>(this DbContext dbcontext, Expression<Func<TEntity, bool>> exp)
|
||||
where TEntity : class, IEntity<TId>
|
||||
{
|
||||
return dbcontext.Set<TEntity>().AsNoTracking()
|
||||
.Where(exp)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public static Task<List<TEntity>> GetListAsync<TEntity, TId>(this DbContext dbcontext,
|
||||
Expression<Func<TEntity, bool>> exp)
|
||||
where TEntity : class, IEntity<TId>
|
||||
{
|
||||
return dbcontext.Set<TEntity>().AsNoTracking()
|
||||
.Where(exp)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public static IQueryable<TEntity> GetListQueryable<TEntity, TId>(this DbContext dbcontext,
|
||||
Expression<Func<TEntity, bool>> exp)
|
||||
where TEntity : class, IEntity<TId>
|
||||
{
|
||||
return dbcontext.Set<TEntity>().AsNoTracking()
|
||||
.Where(exp);
|
||||
}
|
||||
|
||||
public static bool Exists<TEntity, TId>(this DbContext dbcontext, Expression<Func<TEntity, bool>> exp)
|
||||
where TEntity : class, IEntity<TId>
|
||||
{
|
||||
return dbcontext.Set<TEntity>().AsNoTracking()
|
||||
.Any(exp);
|
||||
}
|
||||
|
||||
public static Task<bool> ExistsAsync<TEntity, TId>(this DbContext dbcontext,
|
||||
Expression<Func<TEntity, bool>> exp)
|
||||
where TEntity : class, IEntity<TId>
|
||||
{
|
||||
return dbcontext.Set<TEntity>().AsNoTracking()
|
||||
.AnyAsync(exp);
|
||||
}
|
||||
|
||||
public static List<TEntity> TopN<TEntity, TId>(this DbContext dbcontext,
|
||||
Expression<Func<TEntity, bool>> condition, int topN)
|
||||
where TEntity : class, IEntity<TId>
|
||||
{
|
||||
return dbcontext.Set<TEntity>().AsNoTracking()
|
||||
.Where(condition)
|
||||
.TopN(topN)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public static Task<List<TEntity>> TopNAsync<TEntity, TId>(this DbContext dbcontext,
|
||||
Expression<Func<TEntity, bool>> condition, int topN)
|
||||
where TEntity : class, IEntity<TId>
|
||||
{
|
||||
return dbcontext.Set<TEntity>().AsNoTracking()
|
||||
.Where(condition)
|
||||
.TopN(topN)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
90
Infrastructure/Hncore.Infrastructure/EF/RepositoryBase.cs
Normal file
90
Infrastructure/Hncore.Infrastructure/EF/RepositoryBase.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Hncore.Infrastructure.DDD;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||
|
||||
namespace Hncore.Infrastructure.EF
|
||||
{
|
||||
public class RepositoryBase<TEntity, TId> : IRepository<TEntity, TId>
|
||||
where TEntity : Entity<TId>
|
||||
{
|
||||
protected DbContext Dbcontext;
|
||||
|
||||
public RepositoryBase(IRepositoryDbContext dbContext)
|
||||
{
|
||||
Dbcontext = dbContext.DbContext;
|
||||
}
|
||||
|
||||
public TEntity FindById(TId id)
|
||||
{
|
||||
return Dbcontext.Set<TEntity>().Find(id);
|
||||
}
|
||||
|
||||
public Task<TEntity> FindByIdAsync(TId id)
|
||||
{
|
||||
return Dbcontext.Set<TEntity>().FindAsync(id);
|
||||
}
|
||||
|
||||
public void Add(TEntity entity)
|
||||
{
|
||||
Dbcontext.Set<TEntity>().Add(entity);
|
||||
}
|
||||
|
||||
|
||||
public Task AddAsync(TEntity entity)
|
||||
{
|
||||
return Dbcontext.Set<TEntity>().AddAsync(entity);
|
||||
}
|
||||
/// <summary>
|
||||
/// 批量添加
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
public void AddRange(List<TEntity> entity)
|
||||
{
|
||||
Dbcontext.Set<TEntity>().AddRange(entity);
|
||||
}
|
||||
/// <summary>
|
||||
/// 批量添加
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
public Task AddRangeAsync(List<TEntity> entity)
|
||||
{
|
||||
return Dbcontext.Set<TEntity>().AddRangeAsync(entity);
|
||||
}
|
||||
/// <summary>
|
||||
/// 批量修改
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
public void UpdateRange(List<TEntity> entity)
|
||||
{
|
||||
Dbcontext.Set<TEntity>().UpdateRange(entity);
|
||||
}
|
||||
/// <summary>
|
||||
/// 批量删除
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
public void RemoveRange(List<TEntity> entity)
|
||||
{
|
||||
Dbcontext.Set<TEntity>().RemoveRange(entity);
|
||||
}
|
||||
|
||||
public void Remove(TEntity entity)
|
||||
{
|
||||
Dbcontext.Set<TEntity>().Remove(entity);
|
||||
}
|
||||
public void Update(TEntity entity)
|
||||
{
|
||||
Dbcontext.Set<TEntity>().Update(entity);
|
||||
}
|
||||
|
||||
public IQueryable<TEntity> GetQueryable()
|
||||
{
|
||||
return Dbcontext.Set<TEntity>();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
13
Infrastructure/Hncore.Infrastructure/EF/迁移命令.txt
Normal file
13
Infrastructure/Hncore.Infrastructure/EF/迁移命令.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
vs
|
||||
Add-Migration
|
||||
Update-Database
|
||||
|
||||
|
||||
|
||||
cli
|
||||
dotnet ef migrations add init
|
||||
|
||||
dotnet ef database update
|
||||
|
||||
输出脚本
|
||||
dotnet ef migrations script
|
||||
Reference in New Issue
Block a user