目前,我们使用两台具有相同数据库名称和设置的服务器。我想获取处于事件状态或我可以轻松连接到的连接字符串。举例来说,有时我们在 server-1 所在的地方停电,这样我就可以使用 server-2,因为它位于不同的地方。
这里,我在 .NET 中使用连接字符串帮助程序类,但没有 Entity Framework ,但我无法为 Entity Framework 实现它。
在 web.config 中
<add name="dbAdo1a" connectionString="connection for Server-1" providerName="abc" />
<add name="dbAdo1b" connectionString="connection for Server-2" providerName="abc" />
在 C# 中
public class ConnectionStringHelper
{
private static readonly Timer Timer;
private static readonly ConcurrentDictionary<int, string> BestConnectionStrings;
private const int LoopCount = 3;
static ConnectionStringHelper()
{
BestConnectionStrings = new ConcurrentDictionary<int, string>();
for (var i = 1; i <= LoopCount; i++)
{
GetQuickOneSync(i);
}
Timer = new Timer(Constants.ConnectionRefreshTimeout * 1000);
Timer.Elapsed += async (sender, e) => await HandleTimerElapsed(sender, e).ConfigureAwait(false);
Timer.AutoReset = false;
Timer.Start();
}
public static string GetConnectionString(int wareHouseId)
{
if (!BestConnectionStrings.ContainsKey(wareHouseId))
{
return string.Empty; // just swallow the error if no connection available
}
return BestConnectionStrings[wareHouseId];
}
private static async Task HandleTimerElapsed(object sender, ElapsedEventArgs e)
{
try
{
// Find the quickies for each of the connection strings
var sw = new Stopwatch();
sw.Start();
// TODO - three sets of ConnectionStrings for now, make dynamic
for (var i = 1; i <= LoopCount; i++)
{
await GetQuickOne(i).ConfigureAwait(false);
}
}
catch (Exception ex)
{
}
finally
{
Timer.Start();
}
async Task GetQuickOne(int wareHouseId)
{
var quickone = string.Empty;
var quickest = long.MaxValue;
var sw = new Stopwatch();
for (var c = 'a'; c <= 'z'; c++)
{
var cs = ConfigurationManager.ConnectionStrings[$"dbAdo{wareHouseId}{c}"]?.ConnectionString;
if (string.IsNullOrEmpty(cs)) break;
sw.Restart();
// open connection and see how long it takes
using (var connection = new SqlConnection(cs))
{
try
{
await connection.OpenAsync().ConfigureAwait(false);
}
catch (Exception exception)
{
continue; // move on
}
var milliseconds = sw.ElapsedMilliseconds;
if (milliseconds < quickest) // quickest so far?
{
quickest = milliseconds;
quickone = cs;
}
if (milliseconds <= Constants.ConnectionOkThreshold) // is ok if quickest under the threshold, go no further
{
break;
}
}
}
BestConnectionStrings[wareHouseId] = quickone;
}
}
private static void GetQuickOneSync(int wareHouseId)
{
var quickone = string.Empty;
var quickest = long.MaxValue;
var sw = new Stopwatch();
for (var c = 'a'; c <= 'z'; c++)
{
var cs = ConfigurationManager.ConnectionStrings[$"dbAdo{wareHouseId}{c}"]?.ConnectionString;
if (string.IsNullOrEmpty(cs)) break;
sw.Restart();
// open connection and see how long it takes
using (var connection = new SqlConnection(cs))
{
try
{
connection.Open();
}
catch (Exception exception)
{
continue; // move on
}
var milliseconds = sw.ElapsedMilliseconds;
if (milliseconds < quickest) // quickest so far?
{
quickest = milliseconds;
quickone = cs;
}
if (milliseconds <= Constants.ConnectionOkThreshold) // is ok if quickest under the threshold, go no further
{
break;
}
}
}
if (!string.IsNullOrEmpty(quickone))
BestConnectionStrings[wareHouseId] = quickone;
}
}
我想使用 System.Data.Entity.DbContext 类对 Entity Framework 进行相同的设置。我应该能够从 Web 配置传递连接字符串的名称,并检查它是否有效并且应该重定向到它。
最佳答案
根据您的需求,我可以提出解决方案。我假设您已经为 EF 提供了默认连接字符串。
现在你可以这样做了。
第 1 步。为 EF DB Context 创建扩展方法:
公共(public)静态类ConnectionTools {
public static void CheckConnection(this DbContext source)
{
if (!source.Database.Exists())
{
//TODO: logic to read all your connection string into a list
string connectionStrings = new List<string>();
foreach (var connection in connectionStrings)
{
//set new connection and check
source.Database.Connection.ConnectionString = connection;
if (source.Database.Exists())
{
//break loop
}
}
}
}
}
第 2 步。在调用部分执行如下操作:
-
public void SomeOperation()
{
//assuming you already have your context injected
var employees = _context.CheckConnection().Employees.ToList();
}
关于.net - 动态选择 Entity Framework 中事件可用数据库的连接字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58748979/