我有一个Angular 7前端,它调用一个.NET Core Web API,该API本质上可以转换我的EF-Core层。我是Angular的新手,但实际上我收到以下错误:
A second operation started on this context before a previous operation completed.
This is usually caused by different threads using the same instance of DbContext
我要打2个电话,一个要获取记录计数,另一个要检查周数据是否已处理。导航中使用了计数,另一个模块中调用了星期数据。
Angular服务
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { map, catchError, tap } from 'rxjs/operators';
import { environment } from '../environments/environment';
@Injectable({
providedIn: 'root'
})
export class ConsumerService {
constructor(private http: HttpClient) { }
private extractData(res: Response) {
let body = res;
return body || { };
}
private endpoint = environment.API_URL + "/webapi/Report/";
private httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
};
getCount(): Observable<any> {
return this.http.get(this.endpoint + 'items/count').pipe(map(this.extractData));
}
getOverview(): Observable<any> {
return this.http.get(this.endpoint + 'Overview').pipe(map(this.extractData));
}
导航栏模块
import { Component, OnInit } from "@angular/core";
import { ConsumerService } from "../../services/consumer.service";
@Component({
selector: "app-navbar",
templateUrl: "./navbar.component.html",
styleUrls: ["./navbar.component.css"]
})
export class NavbarComponent implements OnInit {
counts: any;
new: any;
modified: any;
discontinued: any;
constructor(public consumer: ConsumerService) {}
ngOnInit() {
this.consumer.getCount().subscribe((data: {}) => {
this.counts = data;
this.new = this.counts.New;
this.discontinued = this.counts.Deleted;
this.modified = this.counts.Modified;
});
}
}
控制器模块
import { Component, OnInit } from "@angular/core";
import { Subject } from "rxjs";
import { ConsumerService } from "../../services/consumer.service";
@Component({
selector: "app-controller",
templateUrl: "./controller.component.html",
styleUrls: ["./controller.component.css"]
})
export class ControllerComponent implements OnInit {
counts: any;
new: any;
modified: any;
discontinued: any;
currentWeek: any;
allWeeks$: any;
dtOptions: DataTables.Settings = {};
dtTrigger: Subject<any> = new Subject();
constructor(public consumer: ConsumerService) {}
ngOnInit() {
this.dtOptions = {
searching: false,
paging: false,
processing: true,
ordering: false
};
this.consumer.getOverview().subscribe((data: {}) => {
this.counts = data["count"];
this.new = this.counts.New;
this.discontinued = this.counts.Deleted;
this.modified = this.counts.Modified;
this.currentWeek = data["latestEntry"];
this.allWeeks$ = data["allEntries"];
this.dtTrigger.next();
});
}
}
.NET Core API控制器
namespace ReportApi.Controllers
{
[Route("webapi/[controller]")]
[ApiController]
public class ReportController : ControllerBase
{
private StagedReporting _reporting;
public ReportController(StagedReporting reporting)
{
_reporting = reporting;
}
[EnableCors("MyPolicy")]
[HttpGet("Overview")]
public object Overview()
{
var response = new OverviewViewModel();
response.LatestEntry = _reporting.GetLatestEntry();
response.AllEntries = _reporting.GetAllEntries().OrderByDescending(a => a.id).ToList();
response.Count = _reporting.GetChangeCount();
return response;
}
[EnableCors("MyPolicy")]
[HttpGet("items/count")]
public object Report()
{
response = new Dictionary<string, int>();
response = _reporting.GetChangeCount();
return response;
}
}
分段报告
public class StagedReporting : IDisposable
{
private bool _disposed;
private IItemsDbContext _itemsDbContext;
private entry _entry;
public StagedReporting (IItemsDbContext itemsDbContext)
{
_itemsDbContext= itemsDbContext;
_entry = GetLatestEntry();
}
public entry GetLatestEntry()
{
return _itemsDbContext.entry.OrderByDescending(e => e.id).FirstOrDefault();
}
public List<entry> GetAllEntries()
{
return _itemsDbContext.entry.OrderBy(e => e.id).ToList();
}
public virtual Dictionary<string, int> GetChangeCount()
{
var response = new Dictionary<string, int>();
response.Add("New", GetNewEntries().Count);
response.Add("Modified", GetModifiedEntries().Count);
response.Add("Deleted", GetDeletedEntries().Count);
return response;
}
public virtual List<ReportStagedImportNewEntries> GetNewEntries()
{
var newEntries = new List<ReportStagedImportNewEntries>();
if (!_entry.processed.HasValue)
{
newEntries.AddRange(_itemsDbContext.ReportStagedImportNewEntries);
}
return newEntries;
}
}
很显然,我希望能够从Angular进行这些调用而没有问题,但是如上所述,由于EF是线程安全的,因此出现了错误。
当我从导航栏中删除呼叫时,问题停止了。关于如何改进我的代码,接收两次调用结果的任何建议?
谢谢。
答案 0 :(得分:0)
我已经回答了我自己的问题。我将我的StagedReporting创建为Singleton,将其更改为Transient,从而为每个请求创建了一个,这解决了我的问题。