我有一个Asp.net核心2应用程序,我在其中配置了一个带有存储库模式和工作单元的dbContext。
一切正常,我可以在控制器中访问UnitOfWork并获取数据。
我试图访问中间件中的上下文以及另一个项目中的类,但我不知道哪种方法最好。
的DbContext
public class BloggingContext : DbContext
{
public BloggingContext(DbContextOptions<BloggingContext> options)
:base(options)
{ }
public DbSet<Blog> Blogs { get; set; }
...
}
启动
public void ConfigureServices(IServiceCollection services)
{
...
services.AddDbContext<BloggingContext>(options => options.UseMySQL(configuration.GetConnectionString("DefaultDb")));
services.AddScoped<IBloggingContext, BloggingContext>();
services.AddTransient<IUnitOfWork, UnitOfWork>();
...
}
中间件
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseMyMiddleware();
...
}
public class MyMiddleware
{
private readonly RequestDelegate _next;
private readonly IConfiguration _configuration;
private readonly IMemoryCache _memoryCache;
public MyMiddleware(RequestDelegate next, IConfiguration configuration, IMemoryCache memoryCache)
{
_next = next;
_configuration = configuration;
_memoryCache = memoryCache;
}
public Task Invoke(HttpContext httpContext)
{
...
HERE I NEED TO ACCESS DATABASE
...
return _next(httpContext);
}
}
public static class MyMiddlewareExtensions
{
public static IApplicationBuilder UseMyMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<MyMiddleware>();
}
}
我在Invoke功能中所做的是:
var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();
optionsBuilder.UseMySQL(_configuration.GetConnectionString("DefaultDb"));
using (var dbContext = new BloggingContext(optionsBuilder.Options))
{
var blog = dbContext.Blogs.FirstOrDefault();
...
}
我很确定这不是最好的方法。理想的方式是访问,比如我在控制器中访问,直接访问UnitOfWork,但我不知道这是否可行。
另外,我需要在不同项目的类中访问相同的DbCOntext,在这种情况下,我还有另一个问题:如何访问我的web项目的appsettings.json中的Configuration连接字符串。< / p>
有没有人能帮我理解如何在新的asp.net核心2中做到这一点?
此外,如果有人需要更多代码,我不介意分享我所拥有的代码,如果有人帮助他人的话。
提前致谢。
答案 0 :(得分:0)
我找到了MiddleWare的解决方案,但没有找到其他项目中的类。
您只需将IUnitOfWork注入到中间件的调用中即可。
public class MyMiddleware
{
private readonly RequestDelegate _next;
private readonly IConfiguration _configuration;
private readonly IMemoryCache _memoryCache;
public MyMiddleware(RequestDelegate next, IConfiguration configuration,
IMemoryCache memoryCache)
{
_next = next;
_configuration = configuration;
_memoryCache = memoryCache;
}
public Task Invoke(HttpContext httpContext, IUnitOfWork unitOfWork)
{
var myData = _unitoOfWork.Blogs.GetFirst();
...
return _next(httpContext);
}
}
当我播种数据库时,我仍然遇到在我的其他DbContext中调用DbContext的问题。
我有另一个DbContext,我正在创造恐龙。它是一个多租户应用程序,我需要在租户第一次访问系统时创建租户数据库,并为该数据库播种,但我必须从主DbContext中播种它。
public class DbContextTenant : IdentityDbContext<ApplicationUser, ApplicationRole, int>, IDbContextTenant
{
private readonly string _connectionString;
public DbContextTenant(DbContextOptions<SpzContextClient> options, IHttpContextAccessor contextAccessor) : base(options)
{
var tenantId = (int)contextAccessor.HttpContext.Items["TenantId"];
_connectionString = contextAccessor.HttpContext.Items["DbString"].ToString();
SEED DATABASE
HERE IS WHERE I NEED TO CALL THE MAIN DBCONTEXT
}
如何在那里调用主DbCOntext ???
答案 1 :(得分:0)
嗯,这看起来像是一个博客,而不是一个stackoverflow问题...我在回答自己的问题,但如果它可以帮助一个人......这是一个非常富有成效的星期天。
在阅读了很多文章之后,我想出了在租户初始化中获取主要DbContext的最佳方法DbContext是使用服务提供商将其作为注入依赖项来获取。
IServiceProvider serviceProvider
public class DbContextTenant : IdentityDbContext<ApplicationUser, ApplicationRole, int>, IDbContextTenant
{
private readonly string _connectionString;
public DbContextTenant(DbContextOptions<SpzContextClient> options,
IHttpContextAccessor contextAccessor, IServiceProvider serviceProvider) : base(options)
{
var tenantId = (int)contextAccessor.HttpContext.Items["TenantId"];
_connectionString = contextAccessor.HttpContext.Items["DbString"].ToString();
TenantInitialization.Initialize(serviceProvider, this, tenantId);
}
如您所见,我将serviceProvider传递给租户数据库的初始化。这样我可以在其他DbCOntext的初始化中使用主DbContext,访问所有租户。
初始化将是这样的。
public static void Initialize(IServiceProvider serviceProvider, DbContextTenant context, int tenantId)
{
if (((RelationalDatabaseCreator) context.GetService<IDatabaseCreator>()).Exists()) return;
context.Database.EnsureCreated();
LanguageInitialization.Initialize(context);
CountryInitialization.Initialize(context);
using (var DbContext = serviceProvider.GetRequiredService<DbContext>())
{
CompanyInitialization.Initialize(context, contextMaster, tenantId);
}
context.SaveChanges();
}
如果你知道更好的方法,请告诉我。
如果数据库已经存在,它就不会做任何事情。这只是第一次有人访问租户站点,因此我们可以将租户添加到数据库,应用程序自己创建数据库。这种方式很容易创建新客户端(租户),只需在主数据库的clients表中添加一行。
它创建数据库并初始化我们需要的表,如语言,contries ......和公司one,从主DbContext的表Client获取所有信息。
这是一个多租户应用程序,asp.net核心2,代码的单一安装,一个主数据库和每个租户的一个数据库。每个租户都有不同的域名,因此我们使用主机来区分租户。
我遇到很多问题,所以如果有人需要,我会分享这个问题。我很想拥有我现在拥有的所有信息。如果您有任何问题或需要任何代码,我很乐意分享您需要的任何内容。