Master Slave Connection

This commit is contained in:
sunkaixuan
2017-10-24 14:44:33 +08:00
parent 93ad6a089f
commit ddb3c3e17f
7 changed files with 122 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace OrmTest.Demos
{
public class MasterSlave
{
}
}

View File

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

View File

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

View File

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

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

View File

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

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