@@ -65,8 +65,8 @@ namespace HealthMonitor.Core.Cache | |||
if (entity == null) return null; | |||
string id = _m_GetPrimaryKey.Invoke(entity, null) + ""; | |||
if (!_mapper.TryRemove(id, out List<Tuple<string, DateTime>> rels)) return null; | |||
//if (!_mapper.TryRemove(id, out List<Tuple<string, DateTime>> rels)) return null; | |||
if (!_mapper.TryRemove(id, out var rels)) return null; | |||
return rels.Select(e => e.Item1).Distinct(); | |||
} | |||
@@ -81,8 +81,8 @@ namespace HealthMonitor.Core.Cache | |||
} | |||
foreach (var id in _mapper.Keys) | |||
{ | |||
if (!_mapper.TryRemove(id, out List<Tuple<string, DateTime>> rels)) continue; | |||
// if (!_mapper.TryRemove(id, out List<Tuple<string, DateTime>> rels)) continue; | |||
if (!_mapper.TryRemove(id, out var rels)) continue; | |||
var availableList = rels.Where(t => DateTime.Now.Subtract(t.Item2).TotalSeconds < DurableSecond).ToList(); | |||
_mapper.AddOrUpdate(id, | |||
_ => availableList, | |||
@@ -9,7 +9,7 @@ namespace HealthMonitor.Core.Cache | |||
/// </summary> | |||
/// <param name="entityType"></param> | |||
/// <returns></returns> | |||
IEntityCacheHandler GetCacheHandler(Type entityType); | |||
IEntityCacheHandler? GetCacheHandler(Type entityType); | |||
/// <summary> | |||
/// 获取缓存键 | |||
@@ -12,7 +12,7 @@ | |||
/// </summary> | |||
/// <param name="key"></param> | |||
/// <returns></returns> | |||
IEnumerable<object> GetEntitiesCache(string key); | |||
IEnumerable<object>? GetEntitiesCache(string key); | |||
/// <summary> | |||
/// 根据缓存键更新实体 | |||
@@ -32,7 +32,7 @@ | |||
/// 获取并移除指定实体主键映射的所有缓存键 | |||
/// </summary> | |||
/// <param name="id"></param> | |||
IEnumerable<string> UnmapKeyFromEntity(object entity); | |||
IEnumerable<string>? UnmapKeyFromEntity(object entity); | |||
/// <summary> | |||
/// 清理失效(超时)的映射关系 | |||
@@ -9,7 +9,7 @@ namespace HealthMonitor.Core.Common | |||
private readonly string _domain; | |||
private readonly ILogger _logger; | |||
public string Content { get; set; } | |||
public string Content { get; set; }=default!; | |||
public CustomizeStopWatch(string domain, ILogger logger) | |||
{ | |||
@@ -24,9 +24,10 @@ namespace HealthMonitor.Core.Common | |||
{ | |||
if (_sw != null) | |||
{ | |||
_logger.LogInformation($"统计时间[{_domain}],耗时 {_sw.Elapsed.TotalMilliseconds} 毫秒 {Content}"); | |||
_logger.LogInformation("统计时间[{_domain}],耗时 {_sw.Elapsed.TotalMilliseconds} 毫秒 {Content}", _domain, _sw.Elapsed.TotalMilliseconds, Content); | |||
_sw.Stop(); | |||
} | |||
GC.SuppressFinalize(this); | |||
} | |||
} | |||
} |
@@ -96,11 +96,11 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
var exp = BuildPrimaryKeyQueryExp<T>(values); | |||
if (exp == null) return default!; | |||
var entity = _context.Set<T>().FirstOrDefault(exp); | |||
var entity = _context!.Set<T>().FirstOrDefault(exp); | |||
//var entity = _context.Set<T>().Find(values); | |||
if (entity != null) _context.Entry(entity).State = EntityState.Detached; //取消实体跟踪 | |||
return entity; | |||
return entity!; | |||
} | |||
/// <summary> | |||
@@ -111,16 +111,16 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
/// <returns>返回主键值为传入值的实体</returns> | |||
public async Task<T> GetByIDAsync<T>(params object[] values) where T : class | |||
{ | |||
if (IsClose()) return default; | |||
if (IsClose()) return default!; | |||
var exp = BuildPrimaryKeyQueryExp<T>(values); | |||
if (exp == null) return default; | |||
if (exp == null) return default!; | |||
var entity = await _context.Set<T>().FirstOrDefaultAsync(exp); | |||
var entity = await _context!.Set<T>().FirstOrDefaultAsync(exp); | |||
//var entity = await _context.Set<T>().FindAsync(values); | |||
if (entity != null) _context.Entry(entity).State = EntityState.Detached; //取消实体跟踪 | |||
return entity; | |||
return entity!; | |||
} | |||
/// <summary> | |||
@@ -130,8 +130,8 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
/// <returns></returns> | |||
public IQueryable<T> GetAll<T>() where T : class | |||
{ | |||
if (IsClose()) return default; | |||
var result = _context.Set<T>().AsNoTracking().Where(s => true); | |||
if (IsClose()) return default!; | |||
var result = _context!.Set<T>().AsNoTracking().Where(s => true); | |||
return result; | |||
} | |||
@@ -143,8 +143,8 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
/// <returns></returns> | |||
public IQueryable<T> GetMany<T>(Expression<Func<T, bool>> expression) where T : class | |||
{ | |||
if (IsClose()) return default; | |||
var result = _context.Set<T>().AsNoTracking().Where(expression); | |||
if (IsClose()) return default!; | |||
var result = _context!.Set<T>().AsNoTracking().Where(expression); | |||
return result; | |||
} | |||
@@ -158,12 +158,12 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
/// <returns></returns> | |||
public IEnumerable<T> Order<T, TKey>(Func<T, TKey> orderExpression, bool isASC = false) where T : class | |||
{ | |||
if (IsClose()) return default; | |||
if (IsClose()) return default!; | |||
if (isASC) | |||
return _context.Set<T>().AsNoTracking().OrderBy(orderExpression); | |||
return _context!.Set<T>().AsNoTracking().OrderBy(orderExpression); | |||
else | |||
return _context.Set<T>().AsNoTracking().OrderByDescending(orderExpression); | |||
return _context!.Set<T>().AsNoTracking().OrderByDescending(orderExpression); | |||
} | |||
/// <summary> | |||
@@ -176,7 +176,7 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
/// <returns></returns> | |||
public List<T> GetPageList<T, Tkey>(int pageSize, int pageIdx, Expression<Func<T, bool>> expression, Func<T, Tkey> orderExpression) where T : class | |||
{ | |||
if (IsClose()) return default; | |||
if (IsClose()) return default!; | |||
var datas = this.GetMany<T>(expression); | |||
var result = datas.OrderBy(orderExpression).Skip(pageSize * (pageIdx - 1)).Take(pageSize); | |||
@@ -194,7 +194,7 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
/// <returns>分页查询结果</returns> | |||
public async Task<List<T>> GetPageListAsync<T, Tkey>(int pageSize, int pageIdx, Expression<Func<T, bool>> expression, Func<T, Tkey> orderExpression) where T : class | |||
{ | |||
if (IsClose()) return default; | |||
if (IsClose()) return default!; | |||
var datas = this.GetMany<T>(expression); | |||
var result = datas.OrderBy(orderExpression).Skip(pageSize * (pageIdx - 1)).Take(pageSize).AsQueryable(); | |||
@@ -243,23 +243,23 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
/// <returns></returns> | |||
public T AddWithIdentity<T>(T model) where T : class | |||
{ | |||
if (IsClose()) return default; | |||
if (IsClose()) return default!; | |||
T retModel; | |||
try | |||
{ | |||
if (model != null) | |||
{ | |||
_context.Set<T>().Add(model); | |||
_context!.Set<T>().Add(model); | |||
_context.SaveChanges(); | |||
retModel = model; | |||
} | |||
else | |||
retModel = null; | |||
retModel = null!; | |||
} | |||
catch (Exception) | |||
{ | |||
retModel = null; | |||
retModel = null!; | |||
} | |||
return retModel; | |||
@@ -273,23 +273,23 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
/// <returns></returns> | |||
public async Task<T> AddWithIdentityAsync<T>(T model) where T : class | |||
{ | |||
if (IsClose()) return default; | |||
if (IsClose()) return default!; | |||
T retModel; | |||
try | |||
{ | |||
if (model != null) | |||
{ | |||
_context.Set<T>().Add(model); | |||
_context!.Set<T>().Add(model); | |||
await _context.SaveChangesAsync(); | |||
retModel = model; | |||
} | |||
else | |||
retModel = null; | |||
retModel = null!; | |||
} | |||
catch (Exception) | |||
{ | |||
retModel = null; | |||
retModel = null!; | |||
} | |||
return retModel; | |||
@@ -307,14 +307,14 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
{ | |||
if (IsClose()) return; | |||
if (model == null) return; | |||
_context.Set<T>().Add(model); | |||
_context!.Set<T>().Add(model); | |||
} | |||
public void Add(object model) | |||
{ | |||
if (IsClose()) return; | |||
if (model == null) return; | |||
_context.Add(model); | |||
_context!.Add(model); | |||
} | |||
/// <summary> | |||
@@ -325,7 +325,7 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
{ | |||
if (IsClose()) return; | |||
if (models == null || models.Count() == 0) return; | |||
_context.AddRange(models); | |||
_context!.AddRange(models); | |||
} | |||
/// <summary> | |||
@@ -340,14 +340,14 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
if (model == null) return; | |||
try | |||
{ | |||
var entity = _context.Remove(model); | |||
var entity = _context!.Remove(model); | |||
} | |||
catch (InvalidOperationException e) | |||
{ | |||
// 若在追踪列表中已经存在另一个实体和该实体有相同主键(但不是同一个) | |||
// 则找到追踪列表里的实体把它标记为删除 | |||
Type modelType = typeof(T); | |||
var key = _context.Model.FindEntityType(modelType).FindPrimaryKey(); | |||
var key = _context!.Model.FindEntityType(modelType)!.FindPrimaryKey(); | |||
if (key == null) | |||
{ | |||
throw e; | |||
@@ -361,8 +361,8 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
foreach (var p in props) | |||
{ | |||
var clrProp = modelType.GetProperty(p.Name); | |||
var val = clrProp.GetValue(model); | |||
param[idx] = val; | |||
var val = clrProp!.GetValue(model); | |||
param[idx] = val!; | |||
idx++; | |||
} | |||
// 用主键找实体,标记为删除 | |||
@@ -379,7 +379,7 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
{ | |||
if (IsClose()) return; | |||
if (model == null) return; | |||
_context.Remove(model); | |||
_context!.Remove(model); | |||
} | |||
/// <summary> | |||
@@ -390,7 +390,7 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
{ | |||
if (IsClose()) return; | |||
if (models == null || models.Count() == 0) return; | |||
_context.RemoveRange(models); | |||
_context!.RemoveRange(models); | |||
} | |||
/// <summary> | |||
@@ -403,7 +403,7 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
{ | |||
if (IsClose()) return; | |||
if (model == null) return; | |||
var entity = _context.Entry<T>(model); | |||
var entity = _context!.Entry<T>(model); | |||
entity.State = EntityState.Modified; | |||
} | |||
@@ -419,7 +419,7 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
{ | |||
if (IsClose()) return; | |||
if (model == null) return; | |||
var entity = _context.Entry<T>(model); | |||
var entity = _context!.Entry<T>(model); | |||
entity.Property(property).IsModified = true; | |||
} | |||
@@ -427,7 +427,7 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
{ | |||
if (IsClose()) return; | |||
if (model == null) return; | |||
_context.Update(model); | |||
_context!.Update(model); | |||
} | |||
/// <summary> | |||
@@ -438,7 +438,7 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
{ | |||
if (IsClose()) return; | |||
if (models == null || models.Count() == 0) return; | |||
_context.UpdateRange(models); | |||
_context!.UpdateRange(models); | |||
} | |||
#endregion | |||
@@ -450,37 +450,33 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
/// <returns>返回的数据表</returns> | |||
public List<DataTable> CallProcedure(string procName, params DbParameter[] parameters) | |||
{ | |||
if (IsClose()) return default; | |||
if (IsClose()) return default!; | |||
List<DataTable> ret = new List<DataTable>(); | |||
var connection = _context.Database.GetDbConnection(); | |||
DbDataReader reader = null; | |||
DataTable table = null; | |||
using (DbCommand cmd = connection.CreateCommand()) | |||
var connection = _context!.Database.GetDbConnection(); | |||
using DbCommand cmd = connection.CreateCommand(); | |||
IDbContextTransaction tran = _context!.Database.CurrentTransaction!; | |||
if (tran != null) | |||
{ | |||
IDbContextTransaction tran = _context.Database.CurrentTransaction; | |||
if (tran != null) | |||
{ | |||
cmd.Transaction = tran.GetDbTransaction(); | |||
} | |||
cmd.Transaction = tran.GetDbTransaction(); | |||
} | |||
cmd.CommandType = System.Data.CommandType.StoredProcedure; | |||
cmd.CommandText = procName; | |||
cmd.Parameters.AddRange(parameters); | |||
_context.Database.OpenConnection(); | |||
reader = cmd.ExecuteReader(); | |||
cmd.CommandType = System.Data.CommandType.StoredProcedure; | |||
cmd.CommandText = procName; | |||
cmd.Parameters.AddRange(parameters); | |||
_context.Database.OpenConnection(); | |||
DbDataReader? reader = cmd.ExecuteReader(); | |||
DataTable? table = ReaderToDataTable(reader); | |||
ret.Add(table); | |||
while (reader.NextResult()) | |||
{ | |||
table = ReaderToDataTable(reader); | |||
ret.Add(table); | |||
while (reader.NextResult()) | |||
{ | |||
table = ReaderToDataTable(reader); | |||
ret.Add(table); | |||
} | |||
reader.Close(); | |||
//context.Database.CloseConnection(); | |||
return ret; | |||
} | |||
reader.Close(); | |||
//context.Database.CloseConnection(); | |||
return ret; | |||
} | |||
/// <summary> | |||
@@ -495,33 +491,31 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
List<DataTable> ret = new List<DataTable>(); | |||
var connection = _context?.Database.GetDbConnection(); | |||
DbDataReader reader = null; | |||
DataTable table = null; | |||
using (DbCommand cmd = connection!.CreateCommand()) | |||
DbDataReader? reader = null; | |||
DataTable? table = null; | |||
using DbCommand? cmd = connection!.CreateCommand(); | |||
IDbContextTransaction? tran = _context?.Database.CurrentTransaction; | |||
if (tran != null) | |||
{ | |||
IDbContextTransaction tran = _context!.Database.CurrentTransaction; | |||
if (tran != null) | |||
{ | |||
cmd.Transaction = tran.GetDbTransaction(); | |||
} | |||
cmd.Transaction = tran.GetDbTransaction(); | |||
} | |||
cmd.CommandType = System.Data.CommandType.StoredProcedure; | |||
cmd.CommandText = procName; | |||
cmd.Parameters.AddRange(parameters); | |||
await _context.Database.OpenConnectionAsync(); | |||
reader = await cmd.ExecuteReaderAsync(); | |||
cmd.CommandType = System.Data.CommandType.StoredProcedure; | |||
cmd.CommandText = procName; | |||
cmd.Parameters.AddRange(parameters); | |||
await _context!.Database.OpenConnectionAsync(); | |||
reader = await cmd.ExecuteReaderAsync(); | |||
table = ReaderToDataTable(reader); | |||
ret.Add(table); | |||
while (reader.NextResult()) | |||
{ | |||
table = ReaderToDataTable(reader); | |||
ret.Add(table); | |||
while (reader.NextResult()) | |||
{ | |||
table = ReaderToDataTable(reader); | |||
ret.Add(table); | |||
} | |||
reader.Close(); | |||
//context.Database.CloseConnection(); | |||
return ret; | |||
} | |||
reader.Close(); | |||
//context.Database.CloseConnection(); | |||
return ret; | |||
} | |||
/// <summary> | |||
@@ -531,7 +525,7 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
public int Save() | |||
{ | |||
if (IsClose()) return -1; | |||
return _context.SaveChanges(); | |||
return _context!.SaveChanges(); | |||
//以后需要解决并发异常 DbUpdateConcurrencyException | |||
} | |||
@@ -543,7 +537,7 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
public async Task<int> SaveAsync() | |||
{ | |||
if (IsClose()) return -1; | |||
return await _context.SaveChangesAsync(); | |||
return await _context!.SaveChangesAsync(); | |||
//以后需要解决并发异常 DbUpdateConcurrencyException | |||
} | |||
@@ -579,7 +573,7 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
//取消当前对象的跟踪 | |||
foreach (var e in models) | |||
{ | |||
_context.Entry(e).State = EntityState.Detached; | |||
_context!.Entry(e).State = EntityState.Detached; | |||
} | |||
} | |||
@@ -587,19 +581,21 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
{ | |||
if (IsClose()) return; | |||
if (model == null) return; | |||
_context.Entry(model).State = EntityState.Detached; | |||
_context!.Entry(model).State = EntityState.Detached; | |||
} | |||
private DataTable ReaderToDataTable(DbDataReader reader) | |||
{ | |||
if (IsClose()) return default; | |||
if (IsClose()) return default!; | |||
DataTable table = new DataTable(); | |||
for (int i = 0; i < reader.FieldCount; i++) | |||
{ | |||
DataColumn column = new DataColumn(); | |||
column.DataType = reader.GetFieldType(i); | |||
column.ColumnName = reader.GetName(i); | |||
DataColumn column = new() | |||
{ | |||
DataType = reader.GetFieldType(i), | |||
ColumnName = reader.GetName(i) | |||
}; | |||
table.Columns.Add(column); | |||
} | |||
@@ -618,11 +614,11 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
private Expression<Func<T, bool>> BuildPrimaryKeyQueryExp<T>(params object[] values) where T : class | |||
{ | |||
if (values == null || values.Length == 0) return null; | |||
if (values == null || values.Length == 0) return null!; | |||
var keys = _context.Model.FindEntityType(typeof(T)).FindPrimaryKey(); | |||
var keys = _context!.Model.FindEntityType(typeof(T))!.FindPrimaryKey(); | |||
var vals = values; | |||
if (keys.Properties.Count > 1) | |||
if (keys!.Properties.Count > 1) | |||
{ | |||
vals = (vals[0] + "").Trim().Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); | |||
if (vals.Length != keys.Properties.Count) throw new ArgumentOutOfRangeException("主键参数数量不匹配"); | |||
@@ -630,12 +626,12 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl | |||
var parameter = Expression.Parameter(typeof(T)); | |||
var v = StringHelper.ConvertToType(vals[0] + "", keys.Properties[0].ClrType); | |||
var exp = Expression.Equal(Expression.Property(parameter, keys.Properties[0].PropertyInfo), Expression.Constant(v, keys.Properties[0].ClrType)); | |||
var exp = Expression.Equal(Expression.Property(parameter, keys.Properties[0].PropertyInfo!), Expression.Constant(v, keys.Properties[0].ClrType)); | |||
for (int i = 1; i < vals.Length; i++) | |||
{ | |||
v = StringHelper.ConvertToType(vals[i] + "", keys.Properties[i].ClrType); | |||
var right = Expression.Equal(Expression.Property(parameter, keys.Properties[i].PropertyInfo), Expression.Constant(v, keys.Properties[i].ClrType)); | |||
var right = Expression.Equal(Expression.Property(parameter, keys.Properties[i].PropertyInfo!), Expression.Constant(v, keys.Properties[i].ClrType)); | |||
exp = Expression.AndAlso(exp, right); | |||
} | |||
return Expression.Lambda<Func<T, bool>>(exp, parameter); | |||
@@ -25,7 +25,7 @@ namespace HealthMonitor.Core.Dal | |||
/// </summary> | |||
/// <param name="expression"></param> | |||
/// <returns></returns> | |||
T GetFirstOrDefault<T>(Expression<Func<T, bool>> expression) where T : class; | |||
T? GetFirstOrDefault<T>(Expression<Func<T, bool>> expression) where T : class; | |||
Task<T> GetFirstOrDefaultAsync<T>(Expression<Func<T, bool>> expression) where T : class; | |||
@@ -212,7 +212,7 @@ namespace HealthMonitor.Core.Dal | |||
/// <param name="procName">存储过程名</param> | |||
/// <param name="parameters">参数</param> | |||
/// <returns>返回的数据表集合</returns> | |||
Task<List<DataTable>> CallProcedureAsync(string procName, params DbParameter[] parameters); | |||
Task<List<DataTable>?> CallProcedureAsync(string procName, params DbParameter[] parameters); | |||
/// <summary> | |||
/// 提交对数据进行的处理,如无处理返回-1 | |||
@@ -148,7 +148,7 @@ namespace HealthMonitor.Core.Operator.Redis | |||
/// <returns></returns> | |||
public OperateCacheItem GetDelayOperator(DelayOperateTypeEnum type, string key) | |||
{ | |||
switch (type) | |||
switch (type) | |||
{ | |||
case DelayOperateTypeEnum.Insert: | |||
return RedisHelper.HGet<OperateCacheItem>(GpsCardRedisKey_Insert, key); | |||
@@ -159,7 +159,7 @@ namespace HealthMonitor.Core.Operator.Redis | |||
case DelayOperateTypeEnum.Delete: | |||
return RedisHelper.HGet<OperateCacheItem>(GpsCardRedisKey_Delete, key); | |||
} | |||
return null; | |||
return null!; | |||
} | |||
/// <summary> | |||
@@ -242,8 +242,8 @@ namespace HealthMonitor.Core.Operator.Redis | |||
public Dictionary<string, OperateCacheItem> GetBulkInsertOperators() | |||
{ | |||
var operators = Remove(DelayOperateTypeEnum.Insert); | |||
PendingInsertOperators = operators; | |||
return operators; | |||
PendingInsertOperators = operators!; | |||
return operators!; | |||
} | |||
/// <summary> | |||
@@ -253,8 +253,8 @@ namespace HealthMonitor.Core.Operator.Redis | |||
public Dictionary<string, OperateCacheItem> GetBulkUpdateOperators() | |||
{ | |||
var operators = Remove(DelayOperateTypeEnum.Update); | |||
PendingUpdateOperators = operators; | |||
return operators; | |||
PendingUpdateOperators = operators!; | |||
return operators!; | |||
} | |||
/// <summary> | |||
@@ -264,8 +264,8 @@ namespace HealthMonitor.Core.Operator.Redis | |||
public Dictionary<string, OperateCacheItem> GetBulkDeleteOperators() | |||
{ | |||
var operators = Remove(DelayOperateTypeEnum.Delete); | |||
PendingDeleteOperators = operators; | |||
return operators; | |||
PendingDeleteOperators = operators!; | |||
return operators!; | |||
} | |||
public void PushFailureInsertOperators(IEnumerable<OperateCacheItem> operators) | |||
@@ -292,7 +292,7 @@ namespace HealthMonitor.Core.Operator.Redis | |||
var results = RedisHelper.StartPipe(p => p.LRange(Failure_GpsCardRedisKey_Insert, 0, count - 1).LTrim(Failure_GpsCardRedisKey_Insert, count, -1)); | |||
if (results.Length != 2) throw new InvalidOperationException("Redis pipe occur errors"); | |||
var operators = (results[0] as string[]).Select(e => JsonConvert.DeserializeObject<OperateCacheItem>(e)); | |||
var operators = (results[0] as string[])!.Select(e => JsonConvert.DeserializeObject<OperateCacheItem>(e)); | |||
return operators; | |||
} | |||
@@ -302,7 +302,7 @@ namespace HealthMonitor.Core.Operator.Redis | |||
var results = RedisHelper.StartPipe(p => p.LRange(Failure_GpsCardRedisKey_Update, 0, count - 1).LTrim(Failure_GpsCardRedisKey_Update, count, -1)); | |||
if (results.Length != 2) throw new InvalidOperationException("Redis pipe occur errors"); | |||
var operators = (results[0] as string[]).Select(e => JsonConvert.DeserializeObject<OperateCacheItem>(e)); | |||
var operators = (results[0] as string[])!.Select(e => JsonConvert.DeserializeObject<OperateCacheItem>(e)); | |||
return operators; | |||
} | |||
@@ -312,7 +312,7 @@ namespace HealthMonitor.Core.Operator.Redis | |||
var results = RedisHelper.StartPipe(p => p.LRange(Failure_GpsCardRedisKey_Delete, 0, count - 1).LTrim(Failure_GpsCardRedisKey_Delete, count, -1)); | |||
if (results.Length != 2) throw new InvalidOperationException("Redis pipe occur errors"); | |||
var operators = (results[0] as string[]).Select(e => JsonConvert.DeserializeObject<OperateCacheItem>(e)); | |||
var operators = (results[0] as string[])!.Select(e => JsonConvert.DeserializeObject<OperateCacheItem>(e)); | |||
return operators; | |||
} | |||
} | |||
@@ -2,7 +2,7 @@ | |||
{ | |||
public abstract class AopValueBase : IValue<CacheInterceptorContext> | |||
{ | |||
public IValue<CacheInterceptorContext> Next { get; set; } | |||
public IValue<CacheInterceptorContext> Next { get; set; } = default!; | |||
public abstract Task Invoke(CacheInterceptorContext context); | |||
@@ -8,34 +8,34 @@ namespace HealthMonitor.Core.Pipeline.Aop | |||
/// <summary> | |||
/// Aop上下文 | |||
/// </summary> | |||
public AspectContext AopContext { get; set; } | |||
public AspectContext AopContext { get; set; } = default!; | |||
/// <summary> | |||
/// Aop管道阀门 | |||
/// </summary> | |||
public AspectDelegate AopDelegate { get; set; } | |||
public AspectDelegate AopDelegate { get; set; } = default!; | |||
/// <summary> | |||
/// 日志 | |||
/// </summary> | |||
public ILogger Logger { get; set; } | |||
public ILogger Logger { get; set; } = default!; | |||
/// <summary> | |||
/// 被代理方法的返回类型 | |||
/// </summary> | |||
public Type ReturnType { get; set; } | |||
public Type ReturnType { get; set; } = default!; | |||
/// <summary> | |||
/// 被代理方法的引用的实体类型 | |||
/// </summary> | |||
public Type EntityType { get; set; } | |||
public Type EntityType { get; set; } = default!; | |||
/// <summary> | |||
/// 被代理方法是否返回列表 | |||
/// </summary> | |||
public bool IsReturnEnumerable { get; set; } | |||
public bool IsReturnEnumerable { get; set; } = default!; | |||
/// <summary> | |||
/// 被代理方法是否为异步方法 | |||
/// </summary> | |||
public bool IsAsyncMethod { get; set; } | |||
public bool IsAsyncMethod { get; set; } = default!; | |||
/// <summary> | |||
/// 服务请求关联标识 | |||
/// </summary> | |||
public string RequestId { get; set; } | |||
public string RequestId { get; set; } = default!; | |||
} | |||
} |
@@ -22,7 +22,7 @@ namespace HealthMonitor.Core.Pipeline.Aop.Delete | |||
} | |||
var durableManager = context.AopContext.ServiceProvider.GetService<IDurableEntityManager>(); | |||
var cacheHandler = durableManager.GetCacheHandler(entityType); | |||
var cacheHandler = durableManager?.GetCacheHandler(entityType); | |||
//若实体类型不支持缓存,则退出 | |||
if (cacheHandler == null || cacheHandler.DurableSecond <= 0) | |||
{ | |||
@@ -30,10 +30,10 @@ namespace HealthMonitor.Core.Pipeline.Aop.Delete | |||
return; | |||
} | |||
string id = entityType.GetMethod(nameof(IEntity.GetPrimaryKey)).Invoke(param, null) + ""; | |||
string id = entityType!.GetMethod(nameof(IEntity.GetPrimaryKey))?.Invoke(param, null) + ""; | |||
if (!string.IsNullOrEmpty(id)) | |||
{ | |||
string key = durableManager.CalcHistoryCacheKey(entityType, id, paramImei, paramDate); | |||
string key = durableManager!.CalcHistoryCacheKey(entityType, id, paramImei!, paramDate); | |||
if (!string.IsNullOrEmpty(key)) | |||
{ | |||
cacheHandler.DeleteEntityCache(key); | |||
@@ -20,7 +20,7 @@ namespace HealthMonitor.Core.Pipeline.Aop.Delete | |||
} | |||
var durableManager = context.AopContext.ServiceProvider.GetService<IDurableEntityManager>(); | |||
var cacheHandler = durableManager.GetCacheHandler(entityType); | |||
var cacheHandler = durableManager?.GetCacheHandler(entityType); | |||
//若实体类型不支持缓存,则退出 | |||
if (cacheHandler == null || cacheHandler.DurableSecond <= 0) | |||
{ | |||
@@ -28,10 +28,10 @@ namespace HealthMonitor.Core.Pipeline.Aop.Delete | |||
return; | |||
} | |||
string id = entityType.GetMethod(nameof(IEntity.GetPrimaryKey)).Invoke(param, null) + ""; | |||
string id = entityType!.GetMethod(nameof(IEntity.GetPrimaryKey))?.Invoke(param, null) + ""; | |||
if (!string.IsNullOrEmpty(id)) | |||
{ | |||
string key = durableManager.CalcCacheKey(entityType, id); | |||
string key = durableManager!.CalcCacheKey(entityType, id); | |||
if (!string.IsNullOrEmpty(key)) | |||
{ | |||
cacheHandler.DeleteEntityCache(key); | |||
@@ -32,20 +32,20 @@ namespace HealthMonitor.Core.Pipeline.Aop.Query | |||
var entityType = returnType; | |||
bool isEnumerable = false; | |||
if (returnType.GetInterface(typeof(IEnumerable).Name) != null) | |||
if (returnType?.GetInterface(typeof(IEnumerable).Name) != null) | |||
{ | |||
entityType = returnType.GenericTypeArguments.FirstOrDefault(); | |||
isEnumerable = true; | |||
} | |||
context.EntityType = entityType; | |||
context.ReturnType = returnType; | |||
context.EntityType = entityType!; | |||
context.ReturnType = returnType!; | |||
context.IsAsyncMethod = isAsync; | |||
context.IsReturnEnumerable = isEnumerable; | |||
context.RequestId = context.AopContext.Parameters.Length > 3 ? context.AopContext.Parameters[3] + "" : ""; | |||
using (var scope = context.Logger.BeginScope(new Dictionary<string, object> { ["RequestId"] = context.RequestId })) | |||
using (new CustomizeStopWatch($"查询历史aop[{entityType.Name}]", context.Logger)) | |||
using (new CustomizeStopWatch($"查询历史aop[{entityType?.Name}]", context.Logger)) | |||
{ | |||
await InvokeNextAsync(context); | |||
} | |||
@@ -32,20 +32,20 @@ namespace HealthMonitor.Core.Pipeline.Aop.Query | |||
var entityType = returnType; | |||
bool isEnumerable = false; | |||
if (returnType.GetInterface(typeof(IEnumerable).Name) != null) | |||
if (returnType?.GetInterface(typeof(IEnumerable).Name) != null) | |||
{ | |||
entityType = returnType.GenericTypeArguments.FirstOrDefault(); | |||
isEnumerable = true; | |||
} | |||
context.EntityType = entityType; | |||
context.ReturnType = returnType; | |||
context.EntityType = entityType!; | |||
context.ReturnType = returnType!; | |||
context.IsAsyncMethod = isAsync; | |||
context.IsReturnEnumerable = isEnumerable; | |||
context.RequestId = context.AopContext.Parameters.Length > 1 ? context.AopContext.Parameters[1] + "" : ""; | |||
using (var scope = context.Logger.BeginScope(new Dictionary<string, object> { ["RequestId"] = context.RequestId })) | |||
using (new CustomizeStopWatch($"查询aop[{entityType.Name}]", context.Logger)) | |||
using (new CustomizeStopWatch($"查询aop[{entityType?.Name}]", context.Logger)) | |||
{ | |||
await InvokeNextAsync(context); | |||
} | |||
@@ -9,7 +9,7 @@ namespace HealthMonitor.Core.Pipeline.Aop.Query | |||
{ | |||
public class GetOrInsertEntityCacheValue : AopValueBase | |||
{ | |||
private readonly static MethodInfo M_TaskFromResult = typeof(Task).GetMethod(nameof(Task.FromResult)); | |||
private readonly static MethodInfo M_TaskFromResult = typeof(Task).GetMethod(nameof(Task.FromResult))!; | |||
public override async Task Invoke(CacheInterceptorContext context) | |||
{ | |||
@@ -18,11 +18,11 @@ namespace HealthMonitor.Core.Pipeline.Aop.Query | |||
var isAsync = context.IsAsyncMethod; | |||
var isEnumerable = context.IsReturnEnumerable; | |||
var param = context.AopContext.Parameters[0]; | |||
string key = null; | |||
string? key = null; | |||
//读取缓存 | |||
var durableManager = context.AopContext.ServiceProvider.GetService<IDurableEntityManager>(); | |||
var cacheHandler = durableManager.GetCacheHandler(entityType); | |||
var cacheHandler = durableManager?.GetCacheHandler(entityType); | |||
//若实体类型不支持缓存,则退出 | |||
if (cacheHandler == null || cacheHandler.DurableSecond <= 0) | |||
{ | |||
@@ -30,8 +30,8 @@ namespace HealthMonitor.Core.Pipeline.Aop.Query | |||
return; | |||
} | |||
if (param is string) key = durableManager.CalcCacheKey(entityType, param.ToString()); | |||
else if (param is GeneralParam) key = durableManager.CalcCacheKey(entityType, (param as GeneralParam)); | |||
if (param is string) key = durableManager?.CalcCacheKey(entityType, param.ToString()!); | |||
else if (param is GeneralParam) key = durableManager?.CalcCacheKey(entityType, (param as GeneralParam)!); | |||
if (string.IsNullOrEmpty(key)) | |||
{ | |||
@@ -45,7 +45,7 @@ namespace HealthMonitor.Core.Pipeline.Aop.Query | |||
{ | |||
context.Logger.LogInformation($"击中实体缓存{key}"); | |||
returnValue = isEnumerable ? cache : cache.FirstOrDefault(); | |||
returnValue = isEnumerable ? cache : cache.FirstOrDefault()!; | |||
if (isAsync) //&& methodReturnType == typeof(Task<>).MakeGenericType(returnType)) | |||
{ | |||
//反射获取Task<>类型的返回值,相当于Task.FromResult(value); | |||
@@ -28,7 +28,7 @@ namespace HealthMonitor.Core.Pipeline.Aop.Update | |||
return; | |||
} | |||
string id = entityType.GetMethod(nameof(IEntity.GetPrimaryKey)).Invoke(param, null) + ""; | |||
string id = entityType!.GetMethod(nameof(IEntity.GetPrimaryKey))?.Invoke(param, null) + ""; | |||
if (!string.IsNullOrEmpty(id)) | |||
{ | |||
string key = durableManager.CalcCacheKey(entityType, id); | |||
@@ -14,7 +14,7 @@ namespace HealthMonitor.Core.Query.Extensions | |||
try | |||
{ | |||
var parameter = Expression.Parameter(typeof(T)); | |||
Expression propertySelector = Expression.Property(parameter, orderinfo.Key); | |||
Expression propertySelector = Expression.Property(parameter, orderinfo.Key!); | |||
//需要用Expression.Convert转换为object表达式,不然值类型的排序会报错 | |||
var orderby = Expression.Lambda<Func<T, object>>(Expression.Convert(propertySelector, typeof(object)), parameter); | |||
@@ -33,7 +33,7 @@ namespace HealthMonitor.Model.Cache | |||
// 用于存储真实值的字段 | |||
private bool gender; | |||
// private bool gender; | |||
//public int Age | |||
//{ | |||
@@ -109,7 +109,7 @@ namespace HealthMonitor.Util.Entities.Base | |||
var limitedProperties = properties.Where(e => e.GetCustomAttributes(typeof(StringLengthAttribute), false).Length > 0).ToList(); | |||
limitedProperties.ForEach(e => | |||
{ | |||
var attr = (e.GetCustomAttributes(typeof(StringLengthAttribute), false) as StringLengthAttribute[])[0]; | |||
var attr = (e.GetCustomAttributes(typeof(StringLengthAttribute), false) as StringLengthAttribute[])![0]; | |||
int max = attr.MaximumLength; | |||
int min = attr.MinimumLength; | |||
var strValue = e.GetValue(this) + ""; | |||
@@ -3,33 +3,18 @@ using HealthMonitor.Core.Cache; | |||
using HealthMonitor.Core.Dal; | |||
using HealthMonitor.Core.Operator; | |||
using HealthMonitor.Core.Query; | |||
using HealthMonitor.Core.Query.Extensions; | |||
using HealthMonitor.Util.Common.Operator; | |||
using HealthMonitor.Util.Entities.Base; | |||
using HealthMonitor.Util.Models; | |||
using HealthMonitor.WebApi.Controllers.Base; | |||
using Microsoft.AspNetCore.Mvc; | |||
using Microsoft.EntityFrameworkCore; | |||
using Microsoft.Extensions.Logging; | |||
using Newtonsoft.Json; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.ComponentModel.DataAnnotations; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
using HealthMonitor.Core.Aop; | |||
using HealthMonitor.Core.Cache; | |||
using HealthMonitor.Core.Dal; | |||
using HealthMonitor.Core.Dal.Factory; | |||
using HealthMonitor.Core.Operator; | |||
using HealthMonitor.Core.Query; | |||
using HealthMonitor.Core.Query.Extensions; | |||
using HealthMonitor.Util.Common; | |||
using HealthMonitor.Util.Common.Operator; | |||
using HealthMonitor.Util.Entities.Base; | |||
using HealthMonitor.Util.Models; | |||
namespace HealthMonitor.WebApi.Controllers.Base | |||
{ | |||
[Produces("application/json")] | |||
[Produces("application/json")] | |||
[Route("api/GpsCard/[controller]/[action]")] | |||
[ApiController] | |||
public abstract class GpsCardControllerBase<T> : DefaultControllerBase<T> where T : GpsCardEntityBase | |||
@@ -76,13 +61,13 @@ namespace HealthMonitor.WebApi.Controllers.Base | |||
/// <returns></returns> | |||
[HttpPost] | |||
[QueryCacheInterceptor] | |||
public async virtual Task<T> GetFirst([FromBody] GeneralParam conditions, [FromHeader] string requestId) | |||
public async virtual Task<T?> GetFirst([FromBody] GeneralParam conditions, [FromHeader] string requestId) | |||
{ | |||
AssertModelStateIsValid(); | |||
var parser = new QueryExpressionParser<T>(); | |||
var expression = parser.ParserConditions(conditions.Filters); | |||
var list = await _dataAccessor.GetMany(expression).OrderConditions(conditions.OrderBys).Take(1).ToListAsync(); | |||
var expression = parser.ParserConditions(conditions.Filters!); | |||
var list = await _dataAccessor.GetMany(expression).OrderConditions(conditions.OrderBys!).Take(1).ToListAsync(); | |||
return list.Count > 0 ? list[0] : null; | |||
} | |||
@@ -100,8 +85,8 @@ namespace HealthMonitor.WebApi.Controllers.Base | |||
AssertModelStateIsValid(); | |||
var parser = new QueryExpressionParser<T>(); | |||
var expression = parser.ParserConditions(conditions.Filters); | |||
var list = await _dataAccessor.GetMany(expression).OrderConditions(conditions.OrderBys).Take(100).ToListAsync(); | |||
var expression = parser.ParserConditions(conditions.Filters!); | |||
var list = await _dataAccessor.GetMany(expression).OrderConditions(conditions.OrderBys!).Take(100).ToListAsync(); | |||
return list; | |||
} | |||
@@ -17,49 +17,54 @@ namespace HealthMonitor.WebApi.DbLog | |||
_categoryName = categoryName; | |||
} | |||
public IDisposable BeginScope<TState>(TState state) | |||
{ | |||
//ScopeStack.Push(state.ToString()); | |||
return new NoopDisposable(); | |||
} | |||
public IDisposable? BeginScope<TState>(TState state) where TState : notnull | |||
{ | |||
return new NoopDisposable(); | |||
} | |||
//public IDisposable BeginScope<TState>(TState state) | |||
//{ | |||
// //ScopeStack.Push(state.ToString()); | |||
// return new NoopDisposable(); | |||
//} | |||
public bool IsEnabled(LogLevel logLevel) | |||
{ | |||
return logLevel >= EfCoreLogProvider.LogThisAndAbout; | |||
} | |||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) | |||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception, string> formatter) | |||
{ | |||
switch (logLevel) | |||
{ | |||
case LogLevel.Trace: | |||
case LogLevel.Debug: | |||
{ | |||
var content = formatter(state, exception).Replace(Path.DirectorySeparatorChar, '\t'); | |||
var content = formatter(state, exception!).Replace(Path.DirectorySeparatorChar, '\t'); | |||
Serilog.Log.Debug(content); | |||
} | |||
break; | |||
case LogLevel.Information: | |||
{ | |||
var content = formatter(state, exception).Replace(Path.DirectorySeparatorChar, '\t'); | |||
var content = formatter(state, exception!).Replace(Path.DirectorySeparatorChar, '\t'); | |||
Serilog.Log.Information(content); | |||
} | |||
break; | |||
case LogLevel.Warning: | |||
{ | |||
var content = formatter(state, exception).Replace(Path.DirectorySeparatorChar, '\t'); | |||
var content = formatter(state, exception!).Replace(Path.DirectorySeparatorChar, '\t'); | |||
Serilog.Log.Warning(content); | |||
} | |||
break; | |||
case LogLevel.Error: | |||
Serilog.Log.Error(formatter(state, exception)); | |||
Serilog.Log.Error(formatter(state, exception!)); | |||
break; | |||
case LogLevel.Critical: | |||
Serilog.Log.Fatal(formatter(state, exception)); | |||
Serilog.Log.Fatal(formatter(state, exception!)); | |||
break; | |||
} | |||
} | |||
@@ -45,17 +45,17 @@ namespace HealthMonitor.WebApi.HttpLog | |||
public static readonly EventId PipelineEnd = new EventId(101, "RequestPipelineEnd"); | |||
} | |||
private static readonly Func<ILogger, HttpMethod, Uri, string, IDisposable> _beginRequestPipelineScope = | |||
private static readonly Func<ILogger, HttpMethod, Uri, string, IDisposable?> _beginRequestPipelineScope = | |||
LoggerMessage.DefineScope<HttpMethod, Uri, string>( | |||
"HTTP {HttpMethod} {Uri} {CorrelationId}"); | |||
private static readonly Action<ILogger, HttpMethod, Uri, string, Exception> _requestPipelineStart = | |||
private static readonly Action<ILogger, HttpMethod, Uri, string, Exception?> _requestPipelineStart = | |||
LoggerMessage.Define<HttpMethod, Uri, string>( | |||
LogLevel.Information, | |||
EventIds.PipelineStart, | |||
"Start processing HTTP request {HttpMethod} {Uri} [Correlation: {CorrelationId}]"); | |||
private static readonly Action<ILogger, HttpStatusCode, Exception> _requestPipelineEnd = | |||
private static readonly Action<ILogger, HttpStatusCode, Exception?> _requestPipelineEnd = | |||
LoggerMessage.Define<HttpStatusCode>( | |||
LogLevel.Information, | |||
EventIds.PipelineEnd, | |||
@@ -64,7 +64,7 @@ namespace HealthMonitor.WebApi.HttpLog | |||
public static IDisposable BeginRequestPipelineScope(ILogger logger, HttpRequestMessage request) | |||
{ | |||
var correlationId = GetCorrelationIdFromRequest(request); | |||
return _beginRequestPipelineScope(logger, request.Method, request.RequestUri, correlationId); | |||
return _beginRequestPipelineScope(logger, request.Method, request.RequestUri!, correlationId)!; | |||
} | |||
public static void RequestPipelineStart(ILogger logger, HttpRequestMessage request) | |||
@@ -72,7 +72,7 @@ namespace HealthMonitor.WebApi.HttpLog | |||
if (logger.IsEnabled(LogLevel.Trace)) | |||
{ | |||
var correlationId = GetCorrelationIdFromRequest(request); | |||
_requestPipelineStart(logger, request.Method, request.RequestUri, correlationId, null); | |||
_requestPipelineStart(logger, request.Method, request.RequestUri!, correlationId, null); | |||
} | |||
} | |||
@@ -35,7 +35,7 @@ | |||
"ConnectionStrings": { | |||
// 测试环境内网 | |||
"GpsCard_Connection_String": "server=172.19.42.40;port=3305;database=gps_card;uid=root;pwd=telpo#1234;CharSet=utf8;MinimumPoolSize=10;MaximumPoolSize=1000;SslMode=none", | |||
"HealthMonitor_Connection_String": "server=172.19.42.40;port=3305;database=health_monitor;uid=root;pwd=telpo#1234;CharSet=utf8;MinimumPoolSize=10;MaximumPoolSize=1000;SslMode=none", | |||
"HealthMonitor_Connection_String": "server=172.19.42.40;port=3305;database=health_monitor;uid=root;pwd=telpo#1234;CharSet=utf8;MinimumPoolSize=10;MaximumPoolSize=1000;SslMode=none" | |||
// 测试环境公网 | |||
//"GpsCard_Connection_String": "server=139.224.254.18;port=3305;database=gps_card;uid=root;pwd=telpo#1234;CharSet=utf8;MinimumPoolSize=10;MaximumPoolSize=1000;SslMode=none", | |||
// "HealthMonitor_Connection_String": "server=139.224.254.18;port=3305;database=health_monitor;uid=root;pwd=telpo#1234;CharSet=utf8;MinimumPoolSize=10;MaximumPoolSize=1000;SslMode=none" | |||