【问题标题】:Perform two related operations in EF Core在 EF Core 中执行两个相关操作
【发布时间】:2016-12-13 06:50:13
【问题描述】:

在我的 ASP.NET Core 应用程序中,我有 DbContext,其中包含两种类型的实体,例如 Pupils 和 Classes。我想添加一个新班级,获取新班级的 ID 并向班级添加新学生。 我试着这样做:

var Class = new Class{ name = "Math" };
Context.Classes.Add(Class);
await Context.SaveChangesAsync();
var Pupil = new Pupil{ name = "Rem", ClassId = Class.Id };
Context.Pupils.Add(Pupil);
await Context.SaveChangesAsync();

但是我在第二次调用 SaveChangesAsync() 时遇到了错误:

Microsoft.EntityFrameworkCore.DbContext:Error: 发生异常 在数据库中保存更改。 System.InvalidOperationException:第二个操作开始于此 前一个操作完成之前的上下文。任何实例成员 不保证是线程安全的。

我试图以这种方式将所有内容包装在事务中:

using (var transaction = Context.Database.BeginTransaction()) {
    ....
    transaction.Commit();
}

但问题依然存在。

在 EF Core 中执行两个相关操作的正确方法是什么?可以一次性完成吗?

PS:我正在使用带有 Npgsql 提供程序的 PostgreSQL

【问题讨论】:

  • 只是想知道(盲目猜测),如果您分配 await Context.SaveChangesAsync() 的返回值并对其进行处理(例如,如果它为零则返回)会发生什么?又是瞎猜……
  • 另外,您正在调用 await 并且您正在使用 ASP.NET Core...这意味着当此代码执行时您处于控制器操作中,对吧?
  • 操作,猜错了 - 它不起作用,是的,我正在使用 await
  • 您正在为每个请求创建一个新的上下文,并且您在完成后立即处理它,对吗?
  • 是的,没错。当我尝试多次调用 SaveChangesAsync() 时会出现问题

标签: c# entity-framework postgresql asp.net-core entity-framework-core


【解决方案1】:

问题在于在其他地方使用 DB,因为 ASP.NET Core 依赖注入仅创建每个服务的单个实例。 我通过创建一个新范围来解决它

public MyService(IServiceProvider provider) { ... };
....

var Scope = provider.CreateScope();            
var Context = Scope.ServiceProvider.GetService<ShellDbContext>();

【讨论】:

  • 这样就解决了问题。星期四我不确定性能。这是我的做法。公共类存储库 { public MyDbContext _db;公共存储库(IServiceProvider 提供者){ var Scope = provider.CreateScope(); _db = Scope.ServiceProvider.GetService(); } }
  • ServiceLifetime.Transient 也解决了这个问题。 stackoverflow.com/questions/41923804/…
【解决方案2】:

Class.Id 是自增/序列字段吗?可能是 EF 在插入后查询 DB 的值...尝试在第一次保存后添加 Console.WriteLine(Class.Id)await Context.Entry(Class).ReloadAsync()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-15
    • 2020-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多