H Vs 1 anno fa
parent
commit
4597bbfb89
22 ha cambiato i file con 177 aggiunte e 190 eliminazioni
  1. +4
    -4
      HealthMonitor.Core/Cache/EntityCacheHandler.cs
  2. +1
    -1
      HealthMonitor.Core/Cache/IDurableEntityManager.cs
  3. +2
    -2
      HealthMonitor.Core/Cache/IEntityCacheHandler.cs
  4. +3
    -2
      HealthMonitor.Core/Common/CustomizeStopWatch.cs
  5. +91
    -95
      HealthMonitor.Core/Dal/EfCoreImpl/EfCoreDataAccessor.cs
  6. +2
    -2
      HealthMonitor.Core/Dal/IDataAccessor.cs
  7. +11
    -11
      HealthMonitor.Core/Operator/Redis/GpsCardOperatorRedisManager.cs
  8. +1
    -1
      HealthMonitor.Core/Pipeline/Aop/AopValueBase.cs
  9. +8
    -8
      HealthMonitor.Core/Pipeline/Aop/CacheInterceptorContext.cs
  10. +3
    -3
      HealthMonitor.Core/Pipeline/Aop/Delete/DeleteEntityCacheHisValue.cs
  11. +3
    -3
      HealthMonitor.Core/Pipeline/Aop/Delete/DeleteEntityCacheValue.cs
  12. +4
    -4
      HealthMonitor.Core/Pipeline/Aop/Query/AssertValidQueryHisValue.cs
  13. +4
    -4
      HealthMonitor.Core/Pipeline/Aop/Query/AssertValidQueryValue.cs
  14. +6
    -6
      HealthMonitor.Core/Pipeline/Aop/Query/GetOrInsertEntityCacheValue.cs
  15. +1
    -1
      HealthMonitor.Core/Pipeline/Aop/Update/UpdateEntityCacheValue.cs
  16. +1
    -1
      HealthMonitor.Core/Query/Extensions/OrderConditionsExt.cs
  17. +1
    -1
      HealthMonitor.Model/Cache/GpsDevicePerson.cs
  18. +1
    -1
      HealthMonitor.Util/Entities/Base/EntityBase.cs
  19. +8
    -23
      HealthMonitor.WebApi/Controllers/Base/GpsCardControllerBase.cs
  20. +16
    -11
      HealthMonitor.WebApi/DbLog/EfCoreLogger.cs
  21. +5
    -5
      HealthMonitor.WebApi/HttpLog/CustomLoggingScopeHttpMessageHandler.cs
  22. +1
    -1
      HealthMonitor.WebApi/appsettings.test.json

+ 4
- 4
HealthMonitor.Core/Cache/EntityCacheHandler.cs Vedi File

@@ -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,


+ 1
- 1
HealthMonitor.Core/Cache/IDurableEntityManager.cs Vedi File

@@ -9,7 +9,7 @@ namespace HealthMonitor.Core.Cache
/// </summary>
/// <param name="entityType"></param>
/// <returns></returns>
IEntityCacheHandler GetCacheHandler(Type entityType);
IEntityCacheHandler? GetCacheHandler(Type entityType);

/// <summary>
/// 获取缓存键


+ 2
- 2
HealthMonitor.Core/Cache/IEntityCacheHandler.cs Vedi File

@@ -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>
/// 清理失效(超时)的映射关系


+ 3
- 2
HealthMonitor.Core/Common/CustomizeStopWatch.cs Vedi File

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

+ 91
- 95
HealthMonitor.Core/Dal/EfCoreImpl/EfCoreDataAccessor.cs Vedi File

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


+ 2
- 2
HealthMonitor.Core/Dal/IDataAccessor.cs Vedi File

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


+ 11
- 11
HealthMonitor.Core/Operator/Redis/GpsCardOperatorRedisManager.cs Vedi File

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


+ 1
- 1
HealthMonitor.Core/Pipeline/Aop/AopValueBase.cs Vedi File

@@ -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
- 8
HealthMonitor.Core/Pipeline/Aop/CacheInterceptorContext.cs Vedi File

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

+ 3
- 3
HealthMonitor.Core/Pipeline/Aop/Delete/DeleteEntityCacheHisValue.cs Vedi File

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


+ 3
- 3
HealthMonitor.Core/Pipeline/Aop/Delete/DeleteEntityCacheValue.cs Vedi File

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


+ 4
- 4
HealthMonitor.Core/Pipeline/Aop/Query/AssertValidQueryHisValue.cs Vedi File

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


+ 4
- 4
HealthMonitor.Core/Pipeline/Aop/Query/AssertValidQueryValue.cs Vedi File

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


+ 6
- 6
HealthMonitor.Core/Pipeline/Aop/Query/GetOrInsertEntityCacheValue.cs Vedi File

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


+ 1
- 1
HealthMonitor.Core/Pipeline/Aop/Update/UpdateEntityCacheValue.cs Vedi File

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


+ 1
- 1
HealthMonitor.Core/Query/Extensions/OrderConditionsExt.cs Vedi File

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


+ 1
- 1
HealthMonitor.Model/Cache/GpsDevicePerson.cs Vedi File

@@ -33,7 +33,7 @@ namespace HealthMonitor.Model.Cache


// 用于存储真实值的字段
private bool gender;
// private bool gender;

//public int Age
//{


+ 1
- 1
HealthMonitor.Util/Entities/Base/EntityBase.cs Vedi File

@@ -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) + "";


+ 8
- 23
HealthMonitor.WebApi/Controllers/Base/GpsCardControllerBase.cs Vedi File

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



+ 16
- 11
HealthMonitor.WebApi/DbLog/EfCoreLogger.cs Vedi File

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


+ 5
- 5
HealthMonitor.WebApi/HttpLog/CustomLoggingScopeHttpMessageHandler.cs Vedi File

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



+ 1
- 1
HealthMonitor.WebApi/appsettings.test.json Vedi File

@@ -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"


Loading…
Annulla
Salva