Download the following packages first:
- Microsoft.EntityFrameworkCore
- Microsoft.EntityFrameworkCore.Design
- Microsoft.EntityFrameworkCore.SqlServer
- Microsoft.EntityFrameworkCore.Tools
The User class
public class User
{
public long Id { get; set; }
public string Account { get; set; }
public string Password { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
public string Email { get; set; }}public class DbConnectionOption
{
public string MasterConnection { get; set; }
public IList<string> SlaveConnections{ get; set; }}Copy the code
Defining the service Layer
public interface IUserService
{
User Find(long id);
User Insert(User user);
int Delete(Expression<Func<User, bool>> predicate);
}
public class UserService : IUserService
{
private readonly MyTestContext _dbContext;
private readonly ILogger<UserService> _logger;
public UserService(MyTestContext dbContext, ILogger<UserService> logger)
{
_dbContext = dbContext;
_logger = logger;
}
public User Find(long id)
{
_dbContext.ToSlave();
var conn = _dbContext.Database.GetDbConnection().ConnectionString;
_logger.LogInformation($"Find[id={id}] Using '{conn}'");
var user = _dbContext.User.FirstOrDefault(u => u.Id == id);
return user;
}
public User Insert(User user)
{
_dbContext.ToMaster();
var conn = _dbContext.Database.GetDbConnection().ConnectionString;
_logger.LogInformation($"Insert[Account={user.Account}] Using '{conn}'");
_dbContext.User.Add(user);
_dbContext.SaveChanges();
return user;
}
public int Delete(Expression<Func<User,bool>> predicate)
{
_dbContext.ToMaster();
var conn = _dbContext.Database.GetDbConnection().ConnectionString;
_logger.LogInformation($"Delete Using '{conn}'");
return_dbContext.User.Where(predicate).Delete(); }}Copy the code
equilibrium
public class SlaveRoundRobin
{
// List of servers
private readonly IList<string> _items;
/ / lock
private readonly object _syncLock = new object(a);// The index of the currently accessed server starts at -1 because no one is accessing it
private int _currentIndex = - 1;
public SlaveRoundRobin(IOptions<DbConnectionOption> dbConnection)
{
_items = dbConnection.Value.SlaveConnections;
if(_items.Count <= 0 )
{
throw new ArgumentException("no elements.".nameof(SlaveRoundRobin)); }}public string GetNext()
{
lock (this._syncLock)
{
_currentIndex++;
// If the number exceeds, the index returns to 0
if (_currentIndex >= _items.Count)
_currentIndex = 0;
return_items[_currentIndex]; }}}Copy the code
DbContext
public class MyTestContext : DbContext
{
private readonly DbConnectionOption _dbConnection;
private readonly SlaveRoundRobin _slaveRoundRobin;
public MyTestContext(IOptions<DbConnectionOption> options, SlaveRoundRobin slaveRoundRobin)
{
_dbConnection = options.Value;
_slaveRoundRobin = slaveRoundRobin;
}
public virtual DbSet<User> User { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer(_dbConnection.MasterConnection);
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>(entity =>
{
entity.HasIndex(e => e.Account)
.HasName("IX_Account")
.IsUnique();
entity.Property(e => e.Account).HasMaxLength(50);
entity.Property(e => e.Email).HasMaxLength(50);
entity.Property(e => e.Name)
.IsRequired()
.HasMaxLength(50);
entity.Property(e => e.Password).HasMaxLength(50);
entity.Property(e => e.Phone)
.IsRequired()
.HasMaxLength(15);
});
}
public void ToMaster()
{
Database.GetDbConnection().ConnectionString = _dbConnection.MasterConnection;
}
public void ToSlave(){ Database.GetDbConnection().ConnectionString = _slaveRoundRobin.GetNext(); }}Copy the code
use
class Program
{
static void Main(string[] args)
{
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build()
.GetSection("ConnectionStrings");
var serviceProvider = new ServiceCollection()
.AddOptions()
.AddLogging(builder => builder.AddConsole())
.Configure<DbConnectionOption>(configuration)
.AddSingleton<SlaveRoundRobin>()
.AddDbContext<MyTestContext>()
.AddSingleton<IUserService, UserService>()
.BuildServiceProvider();
var userService = serviceProvider.GetRequiredService<IUserService>();
userService.Delete(u => u.Account == "Admin");
var newUser = new User
{
Account = "Admin",
Password = "123",
Name = "Administrator",
Phone = "18811223344",
Email = "[email protected]"
};
userService.Insert(newUser);
var stopwatch = new Stopwatch();
stopwatch.Start();
var user = userService.Find(newUser.Id);
while (user == null)
{
Thread.Sleep(100);
user = userService.Find(newUser.Id);
}
stopwatch.Stop();
Console.WriteLine($"Account:{user.Account}; Name:{user.Name}; Delay:{stopwatch.Elapsed}"); }}Copy the code