忽略
This commit is contained in:
@@ -1,47 +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);
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,121 +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();
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,50 +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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,196 +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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user