この問題のスレッドはたくさんありますが、ほとんどの場合、ループして保存しようとする人のコンテキスト私がやっていることではないIListではなくIQueryableです。MVC Core 2.0 EFコアSqlException:セッション内で他のスレッドが実行されているため、新しいトランザクションは許可されません
コントローラとリポジトリの間でコンテキストが渡される問題が発生しています。私はこの問題を私のアプリのどこかに持っていますが、これを簡単に説明し再現する方法は以下の通りです。
まず、Startup.csで自分のDbContextをサービスとして設定します。
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
次に、注入されるコントローラがあります。最初の2つのセーブは、コントローラーから直接コンテキストを使用すると正常に動作しますが、レポから使用すると、タイトルの例外とともにエラーが発生します。レポに保存しようとする前にコントローラにレコードを保存するとエラーが発生するだけであることに注意してください。 、これは任意のDB書き込み用のエントリポイントである必要があり
public class InitiativeRepository
{
private ApplicationDbContext _context;
private ApplicationUser _user;
public InitiativeRepository(ApplicationDbContext context, ApplicationUser user)
{
_context = context;
_user = user;
}
public Initiative Get(int id, bool eagerLoad = false)
{
if (!eagerLoad)
{
return _context.Initiatives.SingleOrDefault(i => i.Id == id);
}
else
{
return _context.Initiatives.Include(i => i.Tasks).ThenInclude(t => t.ActionItems).
SingleOrDefault(i => i.Id == id);
}
}
public List<Initiative> GetAll()
{
return _context.Initiatives.ToList();
}
public Initiative Update(Initiative Entity)
{
_context.Update(Entity);
_context.SaveChanges(); // This line causes the exception.
return Entity;
}
}
しかし、私は、ASP.NETのIDを使用していますが、このセッションのためで自動ログオンしていますので、私:ここ
private ApplicationDbContext _context;
private UserManager<ApplicationUser> _userManager;
private ApplicationUser _user
{
get
{
return _userManager.GetUserAsync(User).Result;
}
}
public InitiativesController(ApplicationDbContext context, UserManager<ApplicationUser> userManager)
{
_context = context;
_userManager = userManager;
}
// GET: Initiatives
public IActionResult Index()
{
Initiative i2 = new Initiative();
i2.Id = 2;
i2.InitiativeName = "testname";
_context.Update(i2);
_context.SaveChanges(); // Works fine
var i4 = _context.Initiatives.SingleOrDefault(init => init.Id == 2);
i4.InitiativeName = "blep";
_context.Update(i4);
_context.SaveChanges(); // Works fine
InitiativeRepository initiativeRepository = new InitiativeRepository(_context, _user);
var i= initiativeRepository.Get(2);
i.InitiativeName = "blah";
initiativeRepository.Update(i); //Throws exception
var initiatives = initiativeRepository.GetAll();
return View(initiatives);
}
は、リポジトリクラスですそれがこれにも影響を及ぼしているかどうかは分かりません。
最初の2つのUpdates()が実際に何かをしていますか?私が考えることができる唯一の説明は、それらが事実上NO-OPであるということです(DB内のデータは既にあなたが設定しようとしているものなので)。しかし第3のものは実際に変更しようとしていますが、このコードの外からアクティブな結果セットが開かれているためです。 –
うわー、私は文字列リテラルを変更することができ、私はDBに反映された更新を見ることができます。私は、あなたがこのコードの外で開いたアクティブな結果セットを持っているという点で正しいと思います。 VS2017を閉じてもう一度開いたところ、このコードは正常に動作しましたが、アプリのある時点で別の領域が同じエラーメッセージで爆発しました。私はそれを閉じないでいくつかの結果セットを開く必要がありますが、私はどこを把握することはできません。私はまた、なぜこれが断続的であるのか理解していません。 – tarun713