Blazor Service调用偶尔会返回连接错误



我偶尔会从Blazor服务器端的.NET Core项目中得到这个错误。

无法从传输连接读取数据:现有远程主机强制关闭了连接。。

重新加载页面或再次尝试执行相同的函数调用后,将不会出现错误,结果将返回

DbContext定义如下所示:

public class ADPortalDbContext:DbContext
{
public DbSet<Company> Companies { get; set; }
public ADPortalDbContext(DbContextOptions<ADPortalDbContext> options)
: base(options) { }
}

从数据库返回结果的服务如下所示:

公共类CompanyService:ICompanyService{专用只读ADPortalDbContext上下文;

public CompanyService(ADPortalDbContext context)
{
this.context = context;
}
public async Task<IEnumerable<Company>> GetCompaniesSearchText(string searchText)
{
try
{
return await context.Companies
.Where(i => EF.Functions.Like(i.Name.ToLower(), $"%{searchText.ToLower()}%"))
.ToListAsync()
.ConfigureAwait(false);
}
catch(Exception ex)
{
throw new InvalidOperationException("Unable to return results " + ex.Message);
}
} 

Blazor应用程序的Startup.cs如下所示:

services.AddTransient<ICompanyService, CompanyService>();
services.AddDbContext<ADPortalDbContext>(options =>
options.UseMySql(connStr, srvVersion, x =>
{
x.MigrationsAssembly("DCPortal.Infrastructre");
}),
contextLifetime: ServiceLifetime.Transient);

调用该服务的Blazor页面如下所示:

@inject ICompanyService  CompanyService
private async Task<IEnumerable<Company>> SearchCompanies(string searchText)
{
try
{
IEnumerable<Company> companies_ListDb = await CompanyService.GetCompaniesSearchText(searchText);
}
catch(Exception ex)
{
//Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host..
}
}

问题的一般症结在于服务的生存期——DB上下文应该是一次性的;所以在后台,连接在某个时刻被关闭(导致您的错误(。

我发现绕过它的唯一真正方法是实现上下文工厂。

因此,在您的情况下,您将希望在与上下文相同的区域中创建一个文件:

public class ADPortalDbContextFactory : IDbContextFactory<ADPortalDbContext>
{
private readonly DbContextOptions<ADPortalDbContext> options;
public ADPortalDbContextFactory(DbContextOptions<ADPortalDbContext> contextOptions)
{
options = contextOptions;
}
public ADPortalDbContext CreateDbContext()
{
return new ADPortalDbContext(options);
}
}

从那里,你可以对你的创业进行一个简单的调整:

services.AddDbContext<ADPortalDbContext>(options =>
options.UseMySql(connStr, srvVersion, x =>
{
x.MigrationsAssembly("DCPortal.Infrastructre");
}));
services.AddDbContextFactory<ADPortalDbContext, ADPortalDbContextFactory>(options =>
options.UseMySql(connStr, srvVersion, x =>
{
x.MigrationsAssembly("DCPortal.Infrastructre");
}), ServiceLifetime.Scoped);
services.AddScoped<ICompanyService, CompanyService>();

然后您的服务变成:

public class CompanyService : ICompanyService 
{ 
private readonly IDbContextFactory<ADPortalDbContext> contextFactory;

public CompanyService(IDbContextFactory<ADPortalDbContext> context)
{
this.contextFactory = context;
}
public async Task<IEnumerable<Company>> GetCompaniesSearchText(string searchText)
{
try
{
using (var context = contextFactory.CreateDbContext())
{
return await context.Companies
.Where(i => EF.Functions.Like(i.Name.ToLower(), $"%{searchText.ToLower()}%"))
.ToListAsync()
.ConfigureAwait(false);
}
}
catch(Exception ex)
{
throw new InvalidOperationException("Unable to return results " + ex.Message);
}
} 
}

相关内容

  • 没有找到相关文章

最新更新