This commit is contained in:
parent
7aa0418763
commit
7f6a2f0ed1
|
@ -31,6 +31,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.MySql", "samples\Sam
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.SqlServer3x", "samples\Sample.SqlServer3x\Sample.SqlServer3x.csproj", "{447D5357-F095-45DE-9DA5-2D9997237366}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.AbpSharding", "samples\Samples.AbpSharding\Samples.AbpSharding.csproj", "{1136B8C9-3539-42FA-97FD-CAA6F146FCF0}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -73,6 +75,10 @@ Global
|
|||
{447D5357-F095-45DE-9DA5-2D9997237366}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{447D5357-F095-45DE-9DA5-2D9997237366}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{447D5357-F095-45DE-9DA5-2D9997237366}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1136B8C9-3539-42FA-97FD-CAA6F146FCF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1136B8C9-3539-42FA-97FD-CAA6F146FCF0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1136B8C9-3539-42FA-97FD-CAA6F146FCF0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1136B8C9-3539-42FA-97FD-CAA6F146FCF0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -87,6 +93,7 @@ Global
|
|||
{C34FCF48-1A98-4268-BFEE-6C9BFC7FD539} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
|
||||
{90675788-D5C3-415A-9C18-FF159A75B4D5} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
|
||||
{447D5357-F095-45DE-9DA5-2D9997237366} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
|
||||
{1136B8C9-3539-42FA-97FD-CAA6F146FCF0} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {8C07A667-E8B4-43C7-8053-721584BAD291}
|
||||
|
|
|
@ -0,0 +1,556 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Abp.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
using ShardingCore;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
using ShardingCore.DbContexts;
|
||||
using ShardingCore.DbContexts.ShardingDbContexts;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace Samples.AbpSharding
|
||||
{
|
||||
public abstract class AbstractShardingAbpDbContext<T> : AbpDbContext, IShardingTableDbContext<T> where T : DbContext, IShardingTableDbContext
|
||||
{
|
||||
private readonly string EMPTY_SHARDING_TAIL_ID = ShardingConstant.EMPTY_SHARDING_TAIL_ID + Guid.NewGuid().ToString("n");
|
||||
private readonly ConcurrentDictionary<string, DbContext> _dbContextCaches = new ConcurrentDictionary<string, DbContext>();
|
||||
private readonly IVirtualTableManager _virtualTableManager;
|
||||
private readonly IShardingDbContextFactory _shardingDbContextFactory;
|
||||
private readonly IShardingDbContextOptionsBuilderConfig _shardingDbContextOptionsBuilderConfig;
|
||||
private DbContextOptions<T> _dbContextOptions;
|
||||
|
||||
private readonly object CREATELOCK = new object();
|
||||
|
||||
public AbstractShardingAbpDbContext(DbContextOptions options) : base(options)
|
||||
{
|
||||
_shardingDbContextFactory = ShardingContainer.GetService<IShardingDbContextFactory>();
|
||||
_virtualTableManager = ShardingContainer.GetService<IVirtualTableManager>();
|
||||
_shardingDbContextOptionsBuilderConfig = ShardingContainer
|
||||
.GetService<IEnumerable<IShardingDbContextOptionsBuilderConfig>>()
|
||||
.FirstOrDefault(o => o.ShardingDbContextType == ShardingDbContextType);
|
||||
}
|
||||
|
||||
public abstract Type ShardingDbContextType { get; }
|
||||
public Type ActualDbContextType => typeof(T);
|
||||
|
||||
|
||||
private DbContextOptionsBuilder<T> CreateDbContextOptionBuilder()
|
||||
{
|
||||
Type type = typeof(DbContextOptionsBuilder<>);
|
||||
type = type.MakeGenericType(ActualDbContextType);
|
||||
return (DbContextOptionsBuilder<T>)Activator.CreateInstance(type);
|
||||
}
|
||||
|
||||
private DbContextOptions<T> CreateShareDbContextOptions()
|
||||
{
|
||||
var dbContextOptionBuilder = CreateDbContextOptionBuilder();
|
||||
var dbConnection = Database.GetDbConnection();
|
||||
_shardingDbContextOptionsBuilderConfig.UseDbContextOptionsBuilder(dbConnection, dbContextOptionBuilder);
|
||||
return dbContextOptionBuilder.Options;
|
||||
}
|
||||
private DbContextOptions<T> CreateMonopolyDbContextOptions()
|
||||
{
|
||||
var dbContextOptionBuilder = CreateDbContextOptionBuilder();
|
||||
_shardingDbContextOptionsBuilderConfig.UseDbContextOptionsBuilder(dbContextOptionBuilder);
|
||||
return dbContextOptionBuilder.Options;
|
||||
}
|
||||
|
||||
private ShardingDbContextOptions GetShareShardingDbContextOptions(string tail)
|
||||
{
|
||||
if (_dbContextOptions == null)
|
||||
{
|
||||
lock (CREATELOCK)
|
||||
{
|
||||
if (_dbContextOptions == null)
|
||||
{
|
||||
_dbContextOptions = CreateShareDbContextOptions();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new ShardingDbContextOptions(_dbContextOptions, tail);
|
||||
}
|
||||
private ShardingDbContextOptions CetMonopolyShardingDbContextOptions(string tail)
|
||||
{
|
||||
return new ShardingDbContextOptions(CreateMonopolyDbContextOptions(), tail);
|
||||
}
|
||||
|
||||
|
||||
public DbContext GetDbContext(bool track, string tail)
|
||||
{
|
||||
if (track)
|
||||
{
|
||||
if (!_dbContextCaches.TryGetValue(tail, out var dbContext))
|
||||
{
|
||||
dbContext = _shardingDbContextFactory.Create(ShardingDbContextType, GetShareShardingDbContextOptions(tail == EMPTY_SHARDING_TAIL_ID ? string.Empty : tail));
|
||||
_dbContextCaches.TryAdd(tail, dbContext);
|
||||
}
|
||||
|
||||
return dbContext;
|
||||
}
|
||||
else
|
||||
{
|
||||
return _shardingDbContextFactory.Create(ShardingDbContextType, CetMonopolyShardingDbContextOptions(tail == EMPTY_SHARDING_TAIL_ID ? string.Empty : tail));
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsBeginTransaction => Database.CurrentTransaction != null;
|
||||
|
||||
public DbContext CreateGenericDbContext<T>(T entity) where T : class
|
||||
{
|
||||
var tail = EMPTY_SHARDING_TAIL_ID;
|
||||
if (entity.IsShardingTable())
|
||||
{
|
||||
var physicTable = _virtualTableManager.GetVirtualTable(ShardingDbContextType, entity.GetType()).RouteTo(new TableRouteConfig(null, entity as IShardingTable, null))[0];
|
||||
tail = physicTable.Tail;
|
||||
}
|
||||
|
||||
return GetDbContext(true, tail);
|
||||
}
|
||||
|
||||
|
||||
public override EntityEntry Add(object entity)
|
||||
{
|
||||
return CreateGenericDbContext(entity).Add(entity);
|
||||
}
|
||||
|
||||
public override EntityEntry<TEntity> Add<TEntity>(TEntity entity)
|
||||
{
|
||||
return CreateGenericDbContext(entity).Add(entity);
|
||||
}
|
||||
|
||||
|
||||
public override ValueTask<EntityEntry<TEntity>> AddAsync<TEntity>(TEntity entity, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
return CreateGenericDbContext(entity).AddAsync(entity, cancellationToken);
|
||||
}
|
||||
|
||||
public override ValueTask<EntityEntry> AddAsync(object entity, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
return CreateGenericDbContext(entity).AddAsync(entity, cancellationToken);
|
||||
}
|
||||
|
||||
public override void AddRange(params object[] entities)
|
||||
{
|
||||
var groups = entities.Select(o =>
|
||||
{
|
||||
var dbContext = CreateGenericDbContext(o);
|
||||
return new
|
||||
{
|
||||
DbContext = dbContext,
|
||||
Entity = o
|
||||
};
|
||||
}).GroupBy(g => g.DbContext);
|
||||
|
||||
foreach (var group in groups)
|
||||
{
|
||||
group.Key.AddRange(group.Select(o => o.Entity));
|
||||
}
|
||||
}
|
||||
|
||||
public override void AddRange(IEnumerable<object> entities)
|
||||
{
|
||||
var groups = entities.Select(o =>
|
||||
{
|
||||
var dbContext = CreateGenericDbContext(o);
|
||||
return new
|
||||
{
|
||||
DbContext = dbContext,
|
||||
Entity = o
|
||||
};
|
||||
}).GroupBy(g => g.DbContext);
|
||||
|
||||
foreach (var group in groups)
|
||||
{
|
||||
group.Key.AddRange(group.Select(o => o.Entity));
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task AddRangeAsync(params object[] entities)
|
||||
{
|
||||
var groups = entities.Select(o =>
|
||||
{
|
||||
var dbContext = CreateGenericDbContext(o);
|
||||
return new
|
||||
{
|
||||
DbContext = dbContext,
|
||||
Entity = o
|
||||
};
|
||||
}).GroupBy(g => g.DbContext);
|
||||
|
||||
foreach (var group in groups)
|
||||
{
|
||||
await group.Key.AddRangeAsync(group.Select(o => o.Entity));
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task AddRangeAsync(IEnumerable<object> entities, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
var groups = entities.Select(o =>
|
||||
{
|
||||
var dbContext = CreateGenericDbContext(o);
|
||||
return new
|
||||
{
|
||||
DbContext = dbContext,
|
||||
Entity = o
|
||||
};
|
||||
}).GroupBy(g => g.DbContext);
|
||||
|
||||
foreach (var group in groups)
|
||||
{
|
||||
await group.Key.AddRangeAsync(group.Select(o => o.Entity));
|
||||
}
|
||||
}
|
||||
|
||||
public override EntityEntry<TEntity> Attach<TEntity>(TEntity entity)
|
||||
{
|
||||
return CreateGenericDbContext(entity).Attach(entity);
|
||||
}
|
||||
|
||||
public override EntityEntry Attach(object entity)
|
||||
{
|
||||
return CreateGenericDbContext(entity).Attach(entity);
|
||||
}
|
||||
|
||||
public override void AttachRange(params object[] entities)
|
||||
{
|
||||
var groups = entities.Select(o =>
|
||||
{
|
||||
var dbContext = CreateGenericDbContext(o);
|
||||
return new
|
||||
{
|
||||
DbContext = dbContext,
|
||||
Entity = o
|
||||
};
|
||||
}).GroupBy(g => g.DbContext);
|
||||
|
||||
foreach (var group in groups)
|
||||
{
|
||||
group.Key.AttachRange(group.Select(o => o.Entity));
|
||||
}
|
||||
}
|
||||
|
||||
public override void AttachRange(IEnumerable<object> entities)
|
||||
{
|
||||
var groups = entities.Select(o =>
|
||||
{
|
||||
var dbContext = CreateGenericDbContext(o);
|
||||
return new
|
||||
{
|
||||
DbContext = dbContext,
|
||||
Entity = o
|
||||
};
|
||||
}).GroupBy(g => g.DbContext);
|
||||
|
||||
foreach (var group in groups)
|
||||
{
|
||||
group.Key.AttachRange(group.Select(o => o.Entity));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//public override DatabaseFacade Database => _dbContextCaches.Any()
|
||||
// ? _dbContextCaches.First().Value.Database
|
||||
// : GetDbContext(true, string.Empty).Database;
|
||||
|
||||
public override EntityEntry<TEntity> Entry<TEntity>(TEntity entity)
|
||||
{
|
||||
return CreateGenericDbContext(entity).Entry(entity);
|
||||
}
|
||||
|
||||
public override EntityEntry Entry(object entity)
|
||||
{
|
||||
return CreateGenericDbContext(entity).Entry(entity);
|
||||
}
|
||||
|
||||
public override EntityEntry<TEntity> Update<TEntity>(TEntity entity)
|
||||
{
|
||||
return CreateGenericDbContext(entity).Update(entity);
|
||||
}
|
||||
|
||||
public override EntityEntry Update(object entity)
|
||||
{
|
||||
return CreateGenericDbContext(entity).Update(entity);
|
||||
}
|
||||
|
||||
public override void UpdateRange(params object[] entities)
|
||||
{
|
||||
var groups = entities.Select(o =>
|
||||
{
|
||||
var dbContext = CreateGenericDbContext(o);
|
||||
return new
|
||||
{
|
||||
DbContext = dbContext,
|
||||
Entity = o
|
||||
};
|
||||
}).GroupBy(g => g.DbContext);
|
||||
|
||||
foreach (var group in groups)
|
||||
{
|
||||
group.Key.UpdateRange(group.Select(o => o.Entity));
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateRange(IEnumerable<object> entities)
|
||||
{
|
||||
var groups = entities.Select(o =>
|
||||
{
|
||||
var dbContext = CreateGenericDbContext(o);
|
||||
return new
|
||||
{
|
||||
DbContext = dbContext,
|
||||
Entity = o
|
||||
};
|
||||
}).GroupBy(g => g.DbContext);
|
||||
|
||||
foreach (var group in groups)
|
||||
{
|
||||
group.Key.UpdateRange(group.Select(o => o.Entity));
|
||||
}
|
||||
}
|
||||
|
||||
public override EntityEntry<TEntity> Remove<TEntity>(TEntity entity)
|
||||
{
|
||||
return CreateGenericDbContext(entity).Remove(entity);
|
||||
}
|
||||
|
||||
public override EntityEntry Remove(object entity)
|
||||
{
|
||||
return CreateGenericDbContext(entity).Remove(entity);
|
||||
}
|
||||
|
||||
public override void RemoveRange(params object[] entities)
|
||||
{
|
||||
var groups = entities.Select(o =>
|
||||
{
|
||||
var dbContext = CreateGenericDbContext(o);
|
||||
return new
|
||||
{
|
||||
DbContext = dbContext,
|
||||
Entity = o
|
||||
};
|
||||
}).GroupBy(g => g.DbContext);
|
||||
|
||||
foreach (var group in groups)
|
||||
{
|
||||
group.Key.RemoveRange(group.Select(o => o.Entity));
|
||||
}
|
||||
}
|
||||
|
||||
public override void RemoveRange(IEnumerable<object> entities)
|
||||
{
|
||||
var groups = entities.Select(o =>
|
||||
{
|
||||
var dbContext = CreateGenericDbContext(o);
|
||||
return new
|
||||
{
|
||||
DbContext = dbContext,
|
||||
Entity = o
|
||||
};
|
||||
}).GroupBy(g => g.DbContext);
|
||||
|
||||
foreach (var group in groups)
|
||||
{
|
||||
group.Key.RemoveRange(group.Select(o => o.Entity));
|
||||
}
|
||||
}
|
||||
|
||||
public override int SaveChanges()
|
||||
{
|
||||
var isBeginTransaction = IsBeginTransaction;
|
||||
//如果是内部开的事务就内部自己消化
|
||||
if (!isBeginTransaction)
|
||||
{
|
||||
Database.BeginTransaction();
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
|
||||
try
|
||||
{
|
||||
foreach (var dbContextCache in _dbContextCaches)
|
||||
{
|
||||
dbContextCache.Value.Database.UseTransaction(Database.CurrentTransaction.GetDbTransaction());
|
||||
i += dbContextCache.Value.SaveChanges();
|
||||
}
|
||||
|
||||
if (!isBeginTransaction)
|
||||
Database.CurrentTransaction.Commit();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!isBeginTransaction)
|
||||
{
|
||||
Database.CurrentTransaction?.Dispose();
|
||||
foreach (var dbContextCache in _dbContextCaches)
|
||||
{
|
||||
dbContextCache.Value.Database.UseTransaction(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public override int SaveChanges(bool acceptAllChangesOnSuccess)
|
||||
{
|
||||
var isBeginTransaction = IsBeginTransaction;
|
||||
//如果是内部开的事务就内部自己消化
|
||||
if (!isBeginTransaction)
|
||||
{
|
||||
Database.BeginTransaction();
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
|
||||
try
|
||||
{
|
||||
foreach (var dbContextCache in _dbContextCaches)
|
||||
{
|
||||
dbContextCache.Value.Database.UseTransaction(Database.CurrentTransaction.GetDbTransaction());
|
||||
i += dbContextCache.Value.SaveChanges(acceptAllChangesOnSuccess);
|
||||
}
|
||||
|
||||
if (!isBeginTransaction)
|
||||
Database.CurrentTransaction.Commit();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!isBeginTransaction)
|
||||
{
|
||||
Database.CurrentTransaction?.Dispose();
|
||||
foreach (var dbContextCache in _dbContextCaches)
|
||||
{
|
||||
dbContextCache.Value.Database.UseTransaction(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
var isBeginTransaction = IsBeginTransaction;
|
||||
//如果是内部开的事务就内部自己消化
|
||||
if (!isBeginTransaction)
|
||||
{
|
||||
await Database.BeginTransactionAsync(cancellationToken);
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
|
||||
try
|
||||
{
|
||||
foreach (var dbContextCache in _dbContextCaches)
|
||||
{
|
||||
await dbContextCache.Value.Database.UseTransactionAsync(Database.CurrentTransaction.GetDbTransaction(), cancellationToken: cancellationToken);
|
||||
i += await dbContextCache.Value.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
if (!isBeginTransaction)
|
||||
await Database.CurrentTransaction.CommitAsync(cancellationToken);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!isBeginTransaction)
|
||||
{
|
||||
}
|
||||
|
||||
if (Database.CurrentTransaction != null)
|
||||
{
|
||||
await Database.CurrentTransaction.DisposeAsync();
|
||||
foreach (var dbContextCache in _dbContextCaches)
|
||||
{
|
||||
await dbContextCache.Value.Database.UseTransactionAsync(null, cancellationToken: cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public override async Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
var isBeginTransaction = IsBeginTransaction;
|
||||
//如果是内部开的事务就内部自己消化
|
||||
if (!isBeginTransaction)
|
||||
{
|
||||
await Database.BeginTransactionAsync(cancellationToken);
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
|
||||
try
|
||||
{
|
||||
foreach (var dbContextCache in _dbContextCaches)
|
||||
{
|
||||
await dbContextCache.Value.Database.UseTransactionAsync(Database.CurrentTransaction.GetDbTransaction(), cancellationToken: cancellationToken);
|
||||
i += await dbContextCache.Value.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
|
||||
}
|
||||
|
||||
if (!isBeginTransaction)
|
||||
await Database.CurrentTransaction.CommitAsync(cancellationToken);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!isBeginTransaction)
|
||||
if (Database.CurrentTransaction != null)
|
||||
{
|
||||
await Database.CurrentTransaction.DisposeAsync();
|
||||
|
||||
foreach (var dbContextCache in _dbContextCaches)
|
||||
{
|
||||
await dbContextCache.Value.Database.UseTransactionAsync(null, cancellationToken: cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
foreach (var dbContextCache in _dbContextCaches)
|
||||
{
|
||||
try
|
||||
{
|
||||
dbContextCache.Value.Dispose();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
public override async ValueTask DisposeAsync()
|
||||
{
|
||||
foreach (var dbContextCache in _dbContextCaches)
|
||||
{
|
||||
try
|
||||
{
|
||||
await dbContextCache.Value.DisposeAsync();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
await base.DisposeAsync();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Samples.AbpSharding.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class WeatherForecastController : ControllerBase
|
||||
{
|
||||
private static readonly string[] Summaries = new[]
|
||||
{
|
||||
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
|
||||
};
|
||||
|
||||
private readonly ILogger<WeatherForecastController> _logger;
|
||||
|
||||
public WeatherForecastController(ILogger<WeatherForecastController> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IEnumerable<WeatherForecast> Get()
|
||||
{
|
||||
var rng = new Random();
|
||||
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
||||
{
|
||||
Date = DateTime.Now.AddDays(index),
|
||||
TemperatureC = rng.Next(-20, 55),
|
||||
Summary = Summaries[rng.Next(Summaries.Length)]
|
||||
})
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Samples.AbpSharding
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:10431",
|
||||
"sslPort": 0
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "weatherforecast",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"Samples.AbpSharding": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": "true",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "weatherforecast",
|
||||
"applicationUrl": "http://localhost:5000",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Abp.EntityFrameworkCore" Version="6.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\ShardingCore\ShardingCore.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,49 @@
|
|||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Samples.AbpSharding
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public Startup(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
public IConfiguration Configuration { get; }
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
|
||||
services.AddControllers();
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||
{
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
|
||||
namespace Samples.AbpSharding
|
||||
{
|
||||
public class WeatherForecast
|
||||
{
|
||||
public DateTime Date { get; set; }
|
||||
|
||||
public int TemperatureC { get; set; }
|
||||
|
||||
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
||||
|
||||
public string Summary { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
Loading…
Reference in New Issue