Несколько вызовов API из Angular, несколько экземпляров EF Core - Поток безопасно? - PullRequest
0 голосов
/ 08 мая 2019

У меня есть внешний интерфейс Angular 7, который обращается к .NET Core Web 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 звонка, 1, чтобы получить количество записей, другой, чтобы проверить, были ли обработаны данные за недели.Счетчик используется в навигации, данные недели вызываются из другого модуля.

Angular Service

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));
    }

Модуль Navbar

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 Controller

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 является поточно-ориентированным.

Когда я удаляю вызов с панели навигации, проблема прекращается.Любые предложения о том, как улучшить мой код, получить результаты обоих звонков?

Спасибо.

1 Ответ

0 голосов
/ 08 мая 2019

Я ответил на свой вопрос. Я создавал свой StagedReporting как Singleton, я изменил его на Transient и, таким образом, создал один для запроса, и это исправило мою проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...