初始提交

This commit is contained in:
wanyongkang
2020-10-07 20:25:03 +08:00
commit d318014316
3809 changed files with 263103 additions and 0 deletions

View 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
}
}
}

View 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;
}
}
}

View 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);
}
}
}

View 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>());
}
}
}

View File

@@ -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);
}
}
}
}

View 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();
}
}
}

View File

@@ -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;
}
}
}

View 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);
}
}
}

View File

@@ -0,0 +1,9 @@
using Microsoft.EntityFrameworkCore;
namespace Hncore.Infrastructure.EF
{
public interface IQueryDbContext
{
DbContext DbContext { get; }
}
}

View File

@@ -0,0 +1,9 @@
using Microsoft.EntityFrameworkCore;
namespace Hncore.Infrastructure.EF
{
public interface IRepositoryDbContext
{
DbContext DbContext { get; }
}
}

View 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;
}
}
}

View 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();
}
}
}

View 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>();
}
}
}

View File

@@ -0,0 +1,13 @@
vs
Add-Migration
Update-Database
cli
dotnet ef migrations add init
dotnet ef database update
输出脚本
dotnet ef migrations script