如何在使用 EF Core API 响应后将翻译添加到数据库?

How to add translations to database after API response with EF Core?

我需要添加一个项目并使用外部 API 翻译服务将其描述翻译成多种语言(因此它们存在于数据库中,以后可以获取不同语言的项目)。由于翻译需要相当长的时间 - 我首先需要 return 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; }
}

Startupclass、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; }
}

在存储库中,我有以下 AddAddProjectDescriptionTranslation 方法:

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 方法,下一行已经 return 使用当前语言描述添加的项目。翻译器和 Headers 被注入到我的存储库 class.
当前的解决方案给我一个错误(只有在断点跟随异步方法执行时我才能查看):

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'.

这个问题有什么解决办法吗?或者也许是实现相同目标的更好方法?在以当前语言向用户提供响应后,我需要将翻译保存在数据库中(我从前端收到当前语言项目的描述)以优化响应时间。

提前感谢您的宝贵时间!

很难说出您想要实现什么以及您是如何做到的,所以这个答案可能毫无用处。我不确定你是如何处理上下文的,但你必须确保在完成所有调用后处理它。

最直接的方法

public async Task Add(Project project)
{
    using (var projectsContext= new ProjectsContext())
    {     
        // Perform data access using the context
    
        projectsContext.Projects.Add(project);
        projectsContext.SaveChanges();
        await AddProjectDescriptionTranslations(project, projectsContext);
     }
   }
}

private async Task AddProjectDescriptionTranslations(Project project, ProjectsContext projectsContext)
{
    await project.TranslateDescription(translator, headers.LanguageEnum);
    projectsContext.Projects.Update(project);
    projectsContext.SaveChanges();
}

所以,不确定这是否是最好的方法,但我能够通过以下方式解决它:
ProjectContextOnConfiguring 方法添加了另一个构造函数:

public ProjectsContext(string connectionString)
{
    this.connectionString = connectionString;
}

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    if (connectionString != null)
    {
        optionsBuilder.UseMySql(connectionString);
    }
}

已添加 ProjectContextFactory:

public class ProjectsContextFactory
{
    private readonly EnvConfig envConfig;

    public ProjectsContextFactory(IOptions<EnvConfig> envConfig)
    {
        this.envConfig = envConfig.Value;
    }

    public ProjectsContext CreateProjectsContext()
    {
        return new ProjectsContext(envConfig.PROJECTS_DB_CONNECTION_STRING_MASTER);
    }
}

在 Add 和 AddTranslations 方法中进行了以下更改:

public void Add(Project project)
{
    projectsContext.Projects.Add(project);
    projectsContext.SaveChanges();
    AddProjectDescriptionTranslations(project);
}

private async Task AddProjectDescriptionTranslations(Project project)
{
    using (var context = projectsContextFactory.CreateProjectsContext())
    {
        context.Attach(project);
        await project.TranslateDescription(translator, headers.LanguageEnum);
        context.Projects.Update(project);
        context.SaveChanges();
    }
}

它允许我在描述被翻译成其他语言并保存到数据库之前使用当前语言描述和 return API 响应来保存项目。