diff --git a/Src/Asp.Net/SqlServerTest/Demos/A_MasterSlave.cs b/Src/Asp.Net/SqlServerTest/Demos/A_MasterSlave.cs
new file mode 100644
index 000000000..943ea2a62
--- /dev/null
+++ b/Src/Asp.Net/SqlServerTest/Demos/A_MasterSlave.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace OrmTest.Demos
+{
+ public class MasterSlave
+ {
+ }
+}
diff --git a/Src/Asp.Net/SqlServerTest/SqlServerTest.csproj b/Src/Asp.Net/SqlServerTest/SqlServerTest.csproj
index 92a38cddb..97fd5ea18 100644
--- a/Src/Asp.Net/SqlServerTest/SqlServerTest.csproj
+++ b/Src/Asp.Net/SqlServerTest/SqlServerTest.csproj
@@ -59,6 +59,7 @@
+
diff --git a/Src/Asp.Net/SqlSugar/Abstract/AdoProvider/AdoProvider.cs b/Src/Asp.Net/SqlSugar/Abstract/AdoProvider/AdoProvider.cs
index a0f96bc78..7c051139a 100644
--- a/Src/Asp.Net/SqlSugar/Abstract/AdoProvider/AdoProvider.cs
+++ b/Src/Asp.Net/SqlSugar/Abstract/AdoProvider/AdoProvider.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 LogEventCompleted { get; set; }
public virtual Func> ProcessingEventStartingSQL { get; set; }
public virtual Action ErrorEvent { get; set; }
+ public virtual List 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
}
}
diff --git a/Src/Asp.Net/SqlSugar/Entities/ConnectionConfig.cs b/Src/Asp.Net/SqlSugar/Entities/ConnectionConfig.cs
index 31e25eb64..566b0991c 100644
--- a/Src/Asp.Net/SqlSugar/Entities/ConnectionConfig.cs
+++ b/Src/Asp.Net/SqlSugar/Entities/ConnectionConfig.cs
@@ -28,6 +28,11 @@ namespace SqlSugar
///
public ConfigureExternalServices ConfigureExternalServices = _DefaultServices;
private static ConfigureExternalServices _DefaultServices = new ConfigureExternalServices();
+ ///
+ /// If SlaveConnectionStrings has value,ConnectionString is write operation, SlaveConnectionStrings is read operation.
+ /// All operations within a transaction is ConnectionString
+ ///
+ public List SlaveConnectionStrings { get; set; }
}
public class ConfigureExternalServices
diff --git a/Src/Asp.Net/SqlSugar/Entities/SlaveConnectionConfig.cs b/Src/Asp.Net/SqlSugar/Entities/SlaveConnectionConfig.cs
new file mode 100644
index 000000000..b0d3e6497
--- /dev/null
+++ b/Src/Asp.Net/SqlSugar/Entities/SlaveConnectionConfig.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace SqlSugar
+{
+ public class SlaveConnectionConfig
+ {
+ ///
+ ///Default value is 1
+ ///If value is 0 means permanent non execution
+ ///
+ public int HitRate = 1;
+ public string ConnectionString { get; set; }
+ }
+}
diff --git a/Src/Asp.Net/SqlSugar/SqlSugar.csproj b/Src/Asp.Net/SqlSugar/SqlSugar.csproj
index efe4d41f2..96bc013a6 100644
--- a/Src/Asp.Net/SqlSugar/SqlSugar.csproj
+++ b/Src/Asp.Net/SqlSugar/SqlSugar.csproj
@@ -76,6 +76,7 @@
+
@@ -170,6 +171,7 @@
+
diff --git a/Src/Asp.Net/SqlSugar/Utilities/UtilRandom.cs b/Src/Asp.Net/SqlSugar/Utilities/UtilRandom.cs
new file mode 100644
index 000000000..916fb47e8
--- /dev/null
+++ b/Src/Asp.Net/SqlSugar/Utilities/UtilRandom.cs
@@ -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 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;
+ }
+ }
+}