Browse Source

fix: 原 Redis 框架存在超时问题,查询资料发现改框架在高并发情况下表现不佳,更改使用 FreeRedis 框架

master
fajiao 2 years ago
parent
commit
4ba4fd2d03
  1. 29
      Cis.Application/Cis.Application.xml
  2. 4
      Cis.Application/Cm/Service/CmMarkLabelService.cs
  3. 65
      Cis.Application/Core/Center/CameraDataCenter.cs
  4. 36
      Cis.Application/Core/Component/CameraSDK/CameraSdkServer.cs
  5. 29
      Cis.Application/Core/Component/CameraSDK/ICameraSdkServer.cs
  6. 21
      Cis.Application/Core/Component/MarkSeacher/MarkSearcherServer.cs
  7. 7
      Cis.Core/Cache/CacheSetup.cs
  8. 2
      Cis.Core/Cache/SqlSugarCache.cs
  9. 4
      Cis.Core/Cis.Core.csproj
  10. 2
      Cis.Core/CoreConfig.json

29
Cis.Application/Cis.Application.xml

@ -416,19 +416,40 @@
<param name="ip"></param> <param name="ip"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:Cis.Application.Core.Component.PtzServer.ICameraSdkServer.GetPtzInfoById(System.String,EC.Helper.CameraSDK.PtzInfo@)"> <member name="M:Cis.Application.Core.Component.PtzServer.ICameraSdkServer.GetPtzInfoByIp(System.String)">
<summary> <summary>
获取 ptz 获取 ptz
</summary> </summary>
<param name="cameraId"></param> <param name="ip"></param>
<param name="ptzInfo"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:Cis.Application.Core.Component.PtzServer.ICameraSdkServer.GetPtzInfoByIp(System.String,EC.Helper.CameraSDK.PtzInfo@)"> <member name="M:Cis.Application.Core.Component.PtzServer.ICameraSdkServer.GetPtzInfoByIpAsync(System.String)">
<summary> <summary>
获取 ptz 获取 ptz
</summary> </summary>
<param name="ip"></param> <param name="ip"></param>
<returns></returns>
</member>
<member name="M:Cis.Application.Core.Component.PtzServer.ICameraSdkServer.TryGetPtzInfoByIp(System.String,EC.Helper.CameraSDK.PtzInfo@)">
<summary>
获取 ptz
</summary>
<param name="ip"></param>
<param name="ptzInfo"></param>
<returns></returns>
</member>
<member name="M:Cis.Application.Core.Component.PtzServer.ICameraSdkServer.GetPtzInfoByIdAsync(System.String)">
<summary>
获取 ptz
</summary>
<param name="cameraId"></param>
<returns></returns>
</member>
<member name="M:Cis.Application.Core.Component.PtzServer.ICameraSdkServer.TryGetPtzInfoById(System.String,EC.Helper.CameraSDK.PtzInfo@)">
<summary>
获取 ptz
</summary>
<param name="cameraId"></param>
<param name="ptzInfo"></param> <param name="ptzInfo"></param>
<returns></returns> <returns></returns>
</member> </member>

4
Cis.Application/Cm/Service/CmMarkLabelService.cs

@ -26,7 +26,7 @@ public class CmMarkLabelService : IDynamicApiController, ITransient
[HttpPost] [HttpPost]
public async Task<bool> Add([FromForm] CmMarkLabel entity) public async Task<bool> Add([FromForm] CmMarkLabel entity)
{ {
bool ret = _cameraSdk.GetPtzInfoById(entity.CbCameraId.ToString(), out PtzInfo ptzInfo); bool ret = _cameraSdk.TryGetPtzInfoById(entity.CbCameraId.ToString(), out PtzInfo ptzInfo);
if (!ret) return false; if (!ret) return false;
entity.PanPosition = ptzInfo.Pan; entity.PanPosition = ptzInfo.Pan;
entity.TiltPosition = ptzInfo.Tilt; entity.TiltPosition = ptzInfo.Tilt;
@ -37,7 +37,7 @@ public class CmMarkLabelService : IDynamicApiController, ITransient
[HttpPost] [HttpPost]
public async Task<long> AddReturnId([FromForm] CmMarkLabel entity) public async Task<long> AddReturnId([FromForm] CmMarkLabel entity)
{ {
bool ret = _cameraSdk.GetPtzInfoById(entity.CbCameraId.ToString(), out PtzInfo ptzInfo); bool ret = _cameraSdk.TryGetPtzInfoById(entity.CbCameraId.ToString(), out PtzInfo ptzInfo);
if (!ret) return 0; if (!ret) return 0;
entity.PanPosition = ptzInfo.Pan; entity.PanPosition = ptzInfo.Pan;
entity.TiltPosition = ptzInfo.Tilt; entity.TiltPosition = ptzInfo.Tilt;

65
Cis.Application/Core/Center/CameraDataCenter.cs

@ -1,8 +1,8 @@
using Cis.Application.Core.Component.MarkSeacher; using Cis.Application.Core.Component.MarkSeacher;
using Cis.Application.Core.Component.PtzServer; using Cis.Application.Core.Component.PtzServer;
using EC.Helper.CameraSDK; using EC.Helper.CameraSDK;
using FreeRedis;
using StackExchange.Profiling.Internal; using StackExchange.Profiling.Internal;
using StackExchange.Redis;
using System.Collections.Concurrent; using System.Collections.Concurrent;
namespace Cis.Application.Core; namespace Cis.Application.Core;
@ -11,7 +11,7 @@ public class CameraDataCenter : ISingleton
{ {
#region Attr #region Attr
private readonly IDatabase _cache; private readonly RedisClient _cache;
private readonly CameraDataOptions _options; private readonly CameraDataOptions _options;
private readonly ICameraSdkServer _cameraSdkServer; private readonly ICameraSdkServer _cameraSdkServer;
private readonly IMarkSearcherServer _markSearcherServer; private readonly IMarkSearcherServer _markSearcherServer;
@ -25,7 +25,7 @@ public class CameraDataCenter : ISingleton
#endregion Attr #endregion Attr
public CameraDataCenter( public CameraDataCenter(
IDatabase cache, RedisClient cache,
ICameraSdkServer cameraSdkServer, ICameraSdkServer cameraSdkServer,
IMarkSearcherServer markSearcherServer IMarkSearcherServer markSearcherServer
) )
@ -49,11 +49,11 @@ public class CameraDataCenter : ISingleton
private void InitThread() private void InitThread()
{ {
// 初始化 CameraPtzThread // 初始化 CameraPtzThread
RefreshCameraPtzThread = new Thread(() => RefreshCameraPtzThread = new Thread(async () =>
{ {
while (true) while (true)
{ {
RefreshCameraPtzInfos(); await RefreshCameraPtzInfos();
Thread.Sleep(_options.CameraPtz.LoopInterval); Thread.Sleep(_options.CameraPtz.LoopInterval);
} }
}) })
@ -63,20 +63,20 @@ public class CameraDataCenter : ISingleton
// 启动 CameraPtzThread // 启动 CameraPtzThread
RefreshCameraPtzThread.Start(); RefreshCameraPtzThread.Start();
// 初始化 MarkSearcherThread //// 初始化 MarkSearcherThread
RefreshMarkSearcherThread = new Thread(() => //RefreshMarkSearcherThread = new Thread(async () =>
{ //{
while (true) // while (true)
{ // {
RefreshMarkSearchers(); // await RefreshMarkSearchers();
Thread.Sleep(_options.MarkSearcher.LoopInterval); // Thread.Sleep(_options.MarkSearcher.LoopInterval);
} // }
}) //})
{ //{
IsBackground = true// 设置后台线程 // IsBackground = true// 设置后台线程
}; //};
// 启动 MarkSearcherThread //// 启动 MarkSearcherThread
RefreshMarkSearcherThread.Start(); //RefreshMarkSearcherThread.Start();
} }
/// <summary> /// <summary>
@ -84,13 +84,12 @@ public class CameraDataCenter : ISingleton
/// 有待改善,应设置超时计数机制 /// 有待改善,应设置超时计数机制
/// https://blog.csdn.net/qq_28368039/article/details/118597396 /// https://blog.csdn.net/qq_28368039/article/details/118597396
/// </summary> /// </summary>
private async void RefreshCameraPtzInfos() private async Task RefreshCameraPtzInfos()
{ {
HashEntry[] entries = _cache.HashGetAll(CacheInfo.CameraIpCounts); string[] cameraIpList = await _cache.HKeysAsync(CacheInfo.CameraIpCounts);
List<Task> tasks = new(); List<Task> tasks = new();
foreach (HashEntry entry in entries) foreach (string cameraIp in cameraIpList)
{ {
string cameraIp = entry.Name;
tasks.Add(RefreshCameraPtzInfo(cameraIp)); tasks.Add(RefreshCameraPtzInfo(cameraIp));
} }
await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(_options.CameraPtz.Timeout)); await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(_options.CameraPtz.Timeout));
@ -103,21 +102,20 @@ public class CameraDataCenter : ISingleton
/// <returns></returns> /// <returns></returns>
private async Task RefreshCameraPtzInfo(string cameraIp) private async Task RefreshCameraPtzInfo(string cameraIp)
{ {
bool ret = _cameraSdkServer.GetPtzInfoByIp(cameraIp, out PtzInfo ptzInfo); bool ret = _cameraSdkServer.TryGetPtzInfoByIp(cameraIp, out PtzInfo ptzInfo);
if (!ret) return; if (!ret) return;
await _cache.HashSetAsync(CacheInfo.CameraPtzInfos, cameraIp, ptzInfo.ToJson()); await _cache.HSetAsync(CacheInfo.CameraPtzInfos, cameraIp, ptzInfo.ToJson());
} }
/// <summary> /// <summary>
/// 刷新所有 markSearcher /// 刷新所有 markSearcher
/// </summary> /// </summary>
private async void RefreshMarkSearchers() private async Task RefreshMarkSearchers()
{ {
HashEntry[] entries = _cache.HashGetAll(CacheInfo.CameraId2Ip); string[] cameraIdList = await _cache.HKeysAsync(CacheInfo.CameraId2Ip);
List<Task> tasks = new(); List<Task> tasks = new();
foreach (HashEntry entry in entries) foreach (string cameraId in cameraIdList)
{ {
string cameraId = entry.Name;
tasks.Add(RefreshMarkSearcher(cameraId.ToLong())); tasks.Add(RefreshMarkSearcher(cameraId.ToLong()));
} }
await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(_options.CameraPtz.Timeout)); await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(_options.CameraPtz.Timeout));
@ -132,10 +130,11 @@ public class CameraDataCenter : ISingleton
{ {
MarkSearcherBase markSearcher = _markSearcherServer.GetSearcher(cameraId); MarkSearcherBase markSearcher = _markSearcherServer.GetSearcher(cameraId);
if (markSearcher == null) return; if (markSearcher == null) return;
string cameraIp = _cache.HashGet(CacheInfo.CameraId2Ip, cameraId); string cameraIp = await _cache.HGetAsync(CacheInfo.CameraId2Ip, cameraId.ToString());
RedisValue value = _cache.HashGet(CacheInfo.CameraPtzInfos, cameraIp); string ptzInfoStr = await _cache.HGetAsync(CacheInfo.CameraPtzInfos, cameraIp);
if (!value.HasValue) return; if (string.IsNullOrEmpty(ptzInfoStr)) return;
PtzInfo ptzInfo = value.ToString().FromJson<PtzInfo>(); PtzInfo ptzInfo = ptzInfoStr.ToObject<PtzInfo>();
if (ptzInfo == null) return;
markSearcher.UpdateCameraCalcParams(ptzInfo); markSearcher.UpdateCameraCalcParams(ptzInfo);
List<MarkLabelCalcResult> resultList = await markSearcher.SearchAsync(); List<MarkLabelCalcResult> resultList = await markSearcher.SearchAsync();
SearchResultListDict[cameraId] = resultList; SearchResultListDict[cameraId] = resultList;

36
Cis.Application/Core/Component/CameraSDK/CameraSdkServer.cs

@ -1,6 +1,6 @@
using Cis.Application.Core.Component.PtzServer; using Cis.Application.Core.Component.PtzServer;
using EC.Helper.CameraSDK; using EC.Helper.CameraSDK;
using StackExchange.Redis; using FreeRedis;
using System.Collections.Concurrent; using System.Collections.Concurrent;
namespace Cis.Application.Core.Component.CameraSDK; namespace Cis.Application.Core.Component.CameraSDK;
@ -12,7 +12,7 @@ public class CameraSdkServer : ICameraSdkServer, ISingleton
{ {
#region Attr #region Attr
private readonly IDatabase _cache; private readonly RedisClient _cache;
/// <summary> /// <summary>
/// {ip, ICameraSDK} /// {ip, ICameraSDK}
@ -21,7 +21,7 @@ public class CameraSdkServer : ICameraSdkServer, ISingleton
#endregion Attr #endregion Attr
public CameraSdkServer(IDatabase cache) public CameraSdkServer(RedisClient cache)
{ {
_cache = cache; _cache = cache;
} }
@ -54,20 +54,38 @@ public class CameraSdkServer : ICameraSdkServer, ISingleton
#region Main Method #region Main Method
public bool GetPtzInfoById(string cameraId, out PtzInfo ptzInfo) public PtzInfo GetPtzInfoByIp(string ip)
{ {
RedisValue value = _cache.HashGet(CacheInfo.CameraId2Ip, cameraId); bool ret = CameraSdkDict.TryGetValue(ip, out ICameraSDK cameraSDK);
if (!value.HasValue) { ptzInfo = PtzInfo.Default; return false; } if (!ret) return PtzInfo.Default;
string ip = value.ToString(); return cameraSDK.GetPtzInfo();
return GetPtzInfoByIp(ip, out ptzInfo);
} }
public bool GetPtzInfoByIp(string ip, out PtzInfo ptzInfo) public async Task<PtzInfo> GetPtzInfoByIpAsync(string ip)
{
return await Task.Run(() => GetPtzInfoByIp(ip));
}
public bool TryGetPtzInfoByIp(string ip, out PtzInfo ptzInfo)
{ {
bool ret = CameraSdkDict.TryGetValue(ip, out ICameraSDK cameraSDK); bool ret = CameraSdkDict.TryGetValue(ip, out ICameraSDK cameraSDK);
if (!ret) { ptzInfo = PtzInfo.Default; return false; } if (!ret) { ptzInfo = PtzInfo.Default; return false; }
return cameraSDK.TryGetPtzInfo(out ptzInfo); return cameraSDK.TryGetPtzInfo(out ptzInfo);
} }
public async Task<PtzInfo> GetPtzInfoByIdAsync(string cameraId)
{
string ip = await _cache.HGetAsync(CacheInfo.CameraId2Ip, cameraId);
if (string.IsNullOrEmpty(ip)) return PtzInfo.Default;
return GetPtzInfoByIp(ip);
}
public bool TryGetPtzInfoById(string cameraId, out PtzInfo ptzInfo)
{
string ip = _cache.HGet(CacheInfo.CameraId2Ip, cameraId);
if (string.IsNullOrEmpty(ip)) { ptzInfo = PtzInfo.Default; return false; }
return TryGetPtzInfoByIp(ip, out ptzInfo);
}
#endregion Main Method #endregion Main Method
} }

29
Cis.Application/Core/Component/CameraSDK/ICameraSdkServer.cs

@ -37,18 +37,39 @@ public interface ICameraSdkServer
/// <summary> /// <summary>
/// 获取 ptz /// 获取 ptz
/// </summary> /// </summary>
/// <param name="cameraId"></param> /// <param name="ip"></param>
/// <param name="ptzInfo"></param>
/// <returns></returns> /// <returns></returns>
public bool GetPtzInfoById(string cameraId, out PtzInfo ptzInfo); public PtzInfo GetPtzInfoByIp(string ip);
/// <summary> /// <summary>
/// 获取 ptz /// 获取 ptz
/// </summary> /// </summary>
/// <param name="ip"></param> /// <param name="ip"></param>
/// <returns></returns>
public Task<PtzInfo> GetPtzInfoByIpAsync(string ip);
/// <summary>
/// 获取 ptz
/// </summary>
/// <param name="ip"></param>
/// <param name="ptzInfo"></param>
/// <returns></returns>
public bool TryGetPtzInfoByIp(string ip, out PtzInfo ptzInfo);
/// <summary>
/// 获取 ptz
/// </summary>
/// <param name="cameraId"></param>
/// <returns></returns>
public Task<PtzInfo> GetPtzInfoByIdAsync(string cameraId);
/// <summary>
/// 获取 ptz
/// </summary>
/// <param name="cameraId"></param>
/// <param name="ptzInfo"></param> /// <param name="ptzInfo"></param>
/// <returns></returns> /// <returns></returns>
public bool GetPtzInfoByIp(string ip, out PtzInfo ptzInfo); public bool TryGetPtzInfoById(string cameraId, out PtzInfo ptzInfo);
#endregion Main Method #endregion Main Method
} }

21
Cis.Application/Core/Component/MarkSeacher/MarkSearcherServer.cs

@ -2,7 +2,7 @@
using Cis.Application.Cm; using Cis.Application.Cm;
using Cis.Application.Core.Component.PtzServer; using Cis.Application.Core.Component.PtzServer;
using EC.Helper.CameraSDK; using EC.Helper.CameraSDK;
using StackExchange.Redis; using FreeRedis;
using System.Collections.Concurrent; using System.Collections.Concurrent;
namespace Cis.Application.Core.Component.MarkSeacher; namespace Cis.Application.Core.Component.MarkSeacher;
@ -17,7 +17,7 @@ public class MarkSearcherServer : IMarkSearcherServer, ISingleton
private readonly SqlSugarRepository<CbCamera> _cbCameraRep; private readonly SqlSugarRepository<CbCamera> _cbCameraRep;
private readonly SqlSugarRepository<CbCameraParams> _cbCameraParamsRep; private readonly SqlSugarRepository<CbCameraParams> _cbCameraParamsRep;
private readonly SqlSugarRepository<CmMarkLabel> _cmMarkLableRep; private readonly SqlSugarRepository<CmMarkLabel> _cmMarkLableRep;
private readonly IDatabase _cache; private readonly RedisClient _cache;
private readonly ICameraSdkServer _cameraSdkServer; private readonly ICameraSdkServer _cameraSdkServer;
@ -34,7 +34,7 @@ public class MarkSearcherServer : IMarkSearcherServer, ISingleton
#endregion Attr #endregion Attr
public MarkSearcherServer( public MarkSearcherServer(
IDatabase cache, RedisClient cache,
ICameraSdkServer cameraSdkServer ICameraSdkServer cameraSdkServer
) )
{ {
@ -89,7 +89,7 @@ public class MarkSearcherServer : IMarkSearcherServer, ISingleton
if (!ret) return false; if (!ret) return false;
} }
} }
ret = _cameraSdkServer.GetPtzInfoByIp(cbCamera.Ip, out PtzInfo ptzInfo); ret = _cameraSdkServer.TryGetPtzInfoByIp(cbCamera.Ip, out PtzInfo ptzInfo);
if (!ret) return false; if (!ret) return false;
// 创建相机计算参数 // 创建相机计算参数
@ -117,8 +117,8 @@ public class MarkSearcherServer : IMarkSearcherServer, ISingleton
ret = MarkSearcherDict.TryAdd(cameraId, markSearcher); ret = MarkSearcherDict.TryAdd(cameraId, markSearcher);
if (!ret) return false; if (!ret) return false;
// 记录缓存 // 记录缓存
_cache.HashSet(CacheInfo.CameraId2Ip, cbCamera.Id, cbCamera.Ip); _cache.HSet(CacheInfo.CameraId2Ip, cbCamera.Id.ToString(), cbCamera.Ip);
_cache.HashIncrement(CacheInfo.CameraIpCounts, cbCamera.Ip); _cache.HIncrBy(CacheInfo.CameraIpCounts, cbCamera.Ip, 1);
return true; return true;
} }
@ -144,11 +144,10 @@ public class MarkSearcherServer : IMarkSearcherServer, ISingleton
{ {
bool ret = MarkSearcherDict.TryRemove(cameraId, out _); bool ret = MarkSearcherDict.TryRemove(cameraId, out _);
if (!ret) return false; if (!ret) return false;
RedisValue value = _cache.HashGet(CacheInfo.CameraId2Ip, cameraId); string cameraIp = _cache.HGet(CacheInfo.CameraId2Ip, cameraId.ToString());
if (!value.HasValue) return false; if (string.IsNullOrEmpty(cameraIp)) return false;
string cameraIp = (string)value; _cache.HDel(CacheInfo.CameraId2Ip, cameraId.ToString());
_cache.HashDelete(CacheInfo.CameraId2Ip, cameraId); _cache.HIncrBy(CacheInfo.CameraIpCounts, cameraIp, -1);
_cache.HashDecrement(CacheInfo.CameraIpCounts, cameraIp);
//int ipCount = (int)_cache.HashGet(CacheInfo.CameraIpCounts, cameraIp); //int ipCount = (int)_cache.HashGet(CacheInfo.CameraIpCounts, cameraIp);
//if (ipCount <= 0) //if (ipCount <= 0)
//{ //{

7
Cis.Core/Cache/CacheSetup.cs

@ -1,4 +1,4 @@
using StackExchange.Redis; using FreeRedis;
namespace Cis.Core; namespace Cis.Core;
@ -10,11 +10,10 @@ public static class CacheSetup
/// <param name="services"></param> /// <param name="services"></param>
public static void AddCache(this IServiceCollection services) public static void AddCache(this IServiceCollection services)
{ {
services.AddSingleton<IDatabase>(options => services.AddSingleton<RedisClient>(options =>
{ {
var redisOptions = App.GetOptions<RedisOptions>(); var redisOptions = App.GetOptions<RedisOptions>();
ConnectionMultiplexer multiplexer = ConnectionMultiplexer.Connect(redisOptions.ConnectionString); RedisClient cache = new(redisOptions.ConnectionString);
IDatabase cache = multiplexer.GetDatabase();
return cache; return cache;
}); });
} }

2
Cis.Core/Cache/SqlSugarCache.cs

@ -7,7 +7,7 @@ namespace Cis.Core;
/// </summary> /// </summary>
public class SqlSugarCache : ICacheService, ISingleton public class SqlSugarCache : ICacheService, ISingleton
{ {
private static readonly ICache _cache = NewLife.Caching.Cache.Default; private static readonly ICache _cache = Cache.Default;
public void Add<V>(string key, V value) public void Add<V>(string key, V value)
{ {

4
Cis.Core/Cis.Core.csproj

@ -24,16 +24,16 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FreeRedis" Version="1.0.3" />
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.8.2.2" /> <PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.8.2.2" />
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.4.9" /> <PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.4.9" />
<PackageReference Include="Furion.Pure" Version="4.4.9" /> <PackageReference Include="Furion.Pure" Version="4.4.9" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.11" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.11" />
<PackageReference Include="NewLife.Core" Version="10.0.2022.1101" /> <PackageReference Include="NewLife.Core" Version="10.0.2022.1101" />
<PackageReference Include="SqlSugarCore" Version="5.1.3.1" /> <PackageReference Include="SqlSugarCore" Version="5.1.3.1" />
<PackageReference Include="StackExchange.Redis" Version="2.6.80" />
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" /> <PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
</ItemGroup> </ItemGroup>
<ProjectExtensions><VisualStudio><UserProperties coreconfig_1json__JsonSchema="https://download.stackhawk.com/hawk/jsonschema/hawkconfig.json" /></VisualStudio></ProjectExtensions> <ProjectExtensions><VisualStudio><UserProperties coreconfig_1json__JsonSchema="https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json" /></VisualStudio></ProjectExtensions>
</Project> </Project>

2
Cis.Core/CoreConfig.json

@ -9,7 +9,7 @@
//"ConnectionString": "DataSource=./cis.db", //"ConnectionString": "DataSource=./cis.db",
//"DbType": "PostgreSQL", //"DbType": "PostgreSQL",
//"ConnectionString": "HOST=127.0.0.1;PORT=5432;USER ID=pgsql;PASSWORD=123456;DATABASE=cis;", //"ConnectionString": "HOST=127.0.0.1;PORT=5432;USER ID=pgsql;PASSWORD=123456;DATABASE=cis;",
"EnableInitDb": true // "EnableInitDb": false //
} }
] ]
}, },

Loading…
Cancel
Save