mirror of
https://gitee.com/dotnetchina/SqlSugar.git
synced 2025-09-20 02:29:39 +08:00
Master Slave Connection
This commit is contained in:
11
Src/Asp.Net/SqlServerTest/Demos/A_MasterSlave.cs
Normal file
11
Src/Asp.Net/SqlServerTest/Demos/A_MasterSlave.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace OrmTest.Demos
|
||||
{
|
||||
public class MasterSlave
|
||||
{
|
||||
}
|
||||
}
|
@@ -59,6 +59,7 @@
|
||||
<Compile Include="Demos\3_Insert.cs" />
|
||||
<Compile Include="Demos\1_Query.cs" />
|
||||
<Compile Include="Demos\2_Update.cs" />
|
||||
<Compile Include="Demos\A_MasterSlave.cs" />
|
||||
<Compile Include="Models\DataTestInfo.cs" />
|
||||
<Compile Include="Models\DataTestInfo2.cs" />
|
||||
<Compile Include="Models\Enum.cs" />
|
||||
|
@@ -5,6 +5,7 @@ using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
namespace SqlSugar
|
||||
{
|
||||
@@ -55,6 +56,8 @@ namespace SqlSugar
|
||||
public virtual Action<string, SugarParameter[]> LogEventCompleted { get; set; }
|
||||
public virtual Func<string, SugarParameter[], KeyValuePair<string, SugarParameter[]>> ProcessingEventStartingSQL { get; set; }
|
||||
public virtual Action<Exception> ErrorEvent { get; set; }
|
||||
public virtual List<IDbConnection> SlaveConnections { get; set; }
|
||||
public virtual IDbConnection MasterConnection { get; set; }
|
||||
#endregion
|
||||
|
||||
#region Connection
|
||||
@@ -230,6 +233,7 @@ namespace SqlSugar
|
||||
{
|
||||
try
|
||||
{
|
||||
SetConnectionStart(sql);
|
||||
if (this.ProcessingEventStartingSQL != null)
|
||||
ExecuteProcessingSQL(ref sql, parameters);
|
||||
ExecuteBefore(sql, parameters);
|
||||
@@ -238,6 +242,7 @@ namespace SqlSugar
|
||||
if (this.IsClearParameters)
|
||||
sqlCommand.Parameters.Clear();
|
||||
ExecuteAfter(sql, parameters);
|
||||
SetConnectionEnd();
|
||||
return count;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -255,6 +260,7 @@ namespace SqlSugar
|
||||
{
|
||||
try
|
||||
{
|
||||
SetConnectionStart(sql);
|
||||
var isSp = this.CommandType == CommandType.StoredProcedure;
|
||||
if (this.ProcessingEventStartingSQL != null)
|
||||
ExecuteProcessingSQL(ref sql, parameters);
|
||||
@@ -266,6 +272,7 @@ namespace SqlSugar
|
||||
if (this.IsClearParameters)
|
||||
sqlCommand.Parameters.Clear();
|
||||
ExecuteAfter(sql, parameters);
|
||||
SetConnectionEnd();
|
||||
return sqlDataReader;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -279,6 +286,7 @@ namespace SqlSugar
|
||||
{
|
||||
try
|
||||
{
|
||||
SetConnectionStart(sql);
|
||||
if (this.ProcessingEventStartingSQL != null)
|
||||
ExecuteProcessingSQL(ref sql, parameters);
|
||||
ExecuteBefore(sql, parameters);
|
||||
@@ -290,6 +298,7 @@ namespace SqlSugar
|
||||
if (this.IsClearParameters)
|
||||
sqlCommand.Parameters.Clear();
|
||||
ExecuteAfter(sql, parameters);
|
||||
SetConnectionEnd();
|
||||
return ds;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -307,6 +316,7 @@ namespace SqlSugar
|
||||
{
|
||||
try
|
||||
{
|
||||
SetConnectionStart(sql);
|
||||
if (this.ProcessingEventStartingSQL != null)
|
||||
ExecuteProcessingSQL(ref sql, parameters);
|
||||
ExecuteBefore(sql, parameters);
|
||||
@@ -316,6 +326,7 @@ namespace SqlSugar
|
||||
if (this.IsClearParameters)
|
||||
sqlCommand.Parameters.Clear();
|
||||
ExecuteAfter(sql, parameters);
|
||||
SetConnectionEnd();
|
||||
return scalar;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -650,6 +661,48 @@ namespace SqlSugar
|
||||
{
|
||||
return this.Context.CurrentConnectionConfig.IsAutoCloseConnection && this.Transaction == null;
|
||||
}
|
||||
private bool IsMasterSlaveSeparation
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Context.CurrentConnectionConfig.SlaveConnectionStrings.HasValue();
|
||||
}
|
||||
}
|
||||
private void SetConnectionStart(string sql)
|
||||
{
|
||||
if (this.IsMasterSlaveSeparation&&IsRead(sql))
|
||||
{
|
||||
if (this.MasterConnection == null)
|
||||
{
|
||||
this.MasterConnection = this.Connection;
|
||||
}
|
||||
var saves = this.Context.CurrentConnectionConfig.SlaveConnectionStrings.Where(it => it.HitRate > 0).ToList();
|
||||
var currentIndex = UtilRandom.GetRandomIndex(saves.ToDictionary(it => saves.ToList().IndexOf(it), it => it.HitRate));
|
||||
var currentSaveConnection = saves[currentIndex];
|
||||
this.Connection = null;
|
||||
this.Context.CurrentConnectionConfig.ConnectionString = currentSaveConnection.ConnectionString;
|
||||
var connection = this.SlaveConnections.FirstOrDefault(it => it.ToString() == currentSaveConnection.ConnectionString);
|
||||
if (connection == null)
|
||||
{
|
||||
this.SlaveConnections.Add(this.Connection);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void SetConnectionEnd()
|
||||
{
|
||||
if (this.IsMasterSlaveSeparation)
|
||||
{
|
||||
this.Connection = this.MasterConnection;
|
||||
this.Context.CurrentConnectionConfig.ConnectionString = this.MasterConnection.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsRead(string sql)
|
||||
{
|
||||
var sqlLower = sql.ToLower();
|
||||
var result = Regex.IsMatch(sqlLower, "[ ]*select[ ]") && !Regex.IsMatch(sqlLower, "[ ]*insert[ ]|[ ]*update[ ]|[ ]*delete[ ]");
|
||||
return result;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@@ -28,6 +28,11 @@ namespace SqlSugar
|
||||
/// </summary>
|
||||
public ConfigureExternalServices ConfigureExternalServices = _DefaultServices;
|
||||
private static ConfigureExternalServices _DefaultServices = new ConfigureExternalServices();
|
||||
/// <summary>
|
||||
/// If SlaveConnectionStrings has value,ConnectionString is write operation, SlaveConnectionStrings is read operation.
|
||||
/// All operations within a transaction is ConnectionString
|
||||
/// </summary>
|
||||
public List<SlaveConnectionConfig> SlaveConnectionStrings { get; set; }
|
||||
}
|
||||
|
||||
public class ConfigureExternalServices
|
||||
|
17
Src/Asp.Net/SqlSugar/Entities/SlaveConnectionConfig.cs
Normal file
17
Src/Asp.Net/SqlSugar/Entities/SlaveConnectionConfig.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace SqlSugar
|
||||
{
|
||||
public class SlaveConnectionConfig
|
||||
{
|
||||
/// <summary>
|
||||
///Default value is 1
|
||||
///If value is 0 means permanent non execution
|
||||
/// </summary>
|
||||
public int HitRate = 1;
|
||||
public string ConnectionString { get; set; }
|
||||
}
|
||||
}
|
@@ -76,6 +76,7 @@
|
||||
<Compile Include="CacheScheme\CacheSchemeMain.cs" />
|
||||
<Compile Include="Entities\CacheKey.cs" />
|
||||
<Compile Include="Entities\ConditionalModel.cs" />
|
||||
<Compile Include="Entities\SlaveConnectionConfig.cs" />
|
||||
<Compile Include="Enum\ConditionalType.cs" />
|
||||
<Compile Include="Enum\DbType.cs" />
|
||||
<Compile Include="ExpressionsToSql\Subquery\Items\ISubOperation.cs" />
|
||||
@@ -170,6 +171,7 @@
|
||||
<Compile Include="Utilities\Check.cs" />
|
||||
<Compile Include="Utilities\DbExtensions.cs" />
|
||||
<Compile Include="Utilities\ErrorMessage.cs" />
|
||||
<Compile Include="Utilities\UtilRandom.cs" />
|
||||
<Compile Include="Utilities\ValidateExtensions.cs" />
|
||||
<Compile Include="Utilities\UtilConstants.cs" />
|
||||
<Compile Include="Utilities\UtilConvert.cs" />
|
||||
|
33
Src/Asp.Net/SqlSugar/Utilities/UtilRandom.cs
Normal file
33
Src/Asp.Net/SqlSugar/Utilities/UtilRandom.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace SqlSugar
|
||||
{
|
||||
public class UtilRandom
|
||||
{
|
||||
public static Random Random = new Random();
|
||||
public static int GetRandomIndex(Dictionary<int, int> pars)
|
||||
{
|
||||
int maxValue = 0;
|
||||
foreach (var item in pars)
|
||||
{
|
||||
maxValue = +item.Value;
|
||||
}
|
||||
var num = Random.Next(1, maxValue);
|
||||
var result = 0;
|
||||
var endValue = 0;
|
||||
foreach (var item in pars)
|
||||
{
|
||||
var index = pars.ToList().IndexOf(item);
|
||||
var beginValue = index == 0 ? 0 : pars[index - 1];
|
||||
endValue += item.Value;
|
||||
result = item.Key;
|
||||
if (num >= beginValue && num <= endValue)
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user