【发布时间】:2021-01-12 18:54:12
【问题描述】:
我需要添加一个项目并使用外部 API 翻译服务将其描述翻译成多种语言(因此它们存在于数据库中,以后可以获取不同语言的项目)。由于翻译需要相当长的时间 - 我首先需要返回 API 响应,然后翻译描述并将其他语言环境行添加到数据库中。
数据库架构如下所示:
数据库上下文设置:
public class ProjectsContext : DbContext
{
public ProjectsContext(DbContextOptions<ProjectsContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder mb)
{
mb.Entity<Project>().ToTable("Project");
mb.Entity<ProjectLocale>().ToTable("ProjectLocales")
.HasKey(pl => new {pl.ProjectId, pl.Locale});
}
public DbSet<Project> Projects { get; set; }
}
在Startup 类中,ConfigureServices 方法:
services.AddDbContext<ProjectsContext>(options =>
options.UseMySql(envConfig.PROJECTS_DB_CONNECTION_STRING_MASTER));
模型:
public class Project
{
public int Id { get; private set; }
public List<ProjectLocale> ProjectLocales { get; private set; } = new List<ProjectLocale>();
public async Task TranslateDescription(Translator translator, LanguageEnum currentLanguage)
{
ProjectLocales = await translator.Translate(ProjectLocales, currentLanguage);
}
}
public class ProjectLocale
{
public int ProjectId { get; set; }
public string Locale { get; set; }
public string Description { get; set; }
}
在存储库中,我有以下 Add 和 AddProjectDescriptionTranslation 方法:
public void Add(Project project)
{
projectsContext.Projects.Add(project);
projectsContext.SaveChanges();
AddProjectDescriptionTranslations(project);
}
private async Task AddProjectDescriptionTranslations(Project project)
{
await project.TranslateDescription(translator, headers.LanguageEnum);
projectsContext.Projects.Update(project);
projectsContext.SaveChanges();
}
我在控制器的 POST 方法中使用了Add 方法,下一行已经返回了添加的项目以及当前语言的描述。翻译器和标头被注入到我的存储库类中。
当前的解决方案给了我一个错误(只有在我使用断点执行异步方法时才能查看):
Cannot access a disposed object. A common cause of this error is disposing a context that was
resolved from dependency injection and then later trying to use the same context instance
elsewhere in your application. This may occur if you are calling Dispose() on the context,
or wrapping the context in a using statement. If you are using dependency injection, you should
let the dependency injection container take care of disposing context instances.
Object name: 'ProjectsContext'.
这个问题有什么解决办法吗?或者也许是实现相同目标的更好方法?在以当前语言向用户提供响应后,我需要将翻译保存在数据库中(我从前端收到当前语言项目的描述)以优化响应时间。
提前感谢您的宝贵时间!
【问题讨论】:
-
您将上下文添加为
Scoped,在您返回结果后将被丢弃。我的建议是使用Queue服务/后台工作进程和IHostedService/.Net Channel。如果您正在使用微服务并希望实现无状态,那么使用队列将是一个更好的选择,如果您确定始终使用单个实例,那么可能可以更简单地选择使用 IHostedService 或任何插件(如 Hangfire)作为后台任务。或者您可以查看 .Net 频道。我还没有亲自玩过它,我认为它类似于队列服务。
标签: c# asp.net-core async-await asp.net-core-3.1 ef-core-3.1