Пользовательский конвертер - вторая операция, запущенная в этом контексте до завершения предыдущей операции - PullRequest
0 голосов
/ 03 марта 2020

Я видел много вопросов и ответов об этой DbContext ошибке множественного доступа, но я действительно не могу выяснить свой случай.

Я использую Db Co ntext с DependencyInjection в custom converter для моего datatable, чтобы я мог показать настраиваемое поле связанной сущности на основе свойства строки.

Это наш случай:

Настраиваемый преобразователь (соответствующая часть):

public class IdToEntityConverter : IValueConverter
{
    public IdToEntityConverter()
    {
    }


    public object Convert(object valueObj, Type targetType, object parameter, CultureInfo culture)
    {
        if (parameter == null || ((ConverterEntities?)parameter) == null)
            return valueObj;

        return ParseParameter(valueObj, parameter).GetAwaiter().GetResult();
    }

    private async Task<object> ParseParameter(object valueObj, object parameter)
    {
        Func<int> valueAsInt = () => valueObj?.AsInt() ?? 0;
        IDependencyResolver dependencyResolver = ((App)Application.Current).ServiceProvider.GetService(typeof(IDependencyResolver)) as IDependencyResolver;
        var myService = dependencyResolver.Resolve<IMyService>();
        return myService.FirstOrDefault(x => x.Id == valueAsInt())?.MyProperty;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

IMyService

public interface IMyService: ICrudService<MyService>
{
}

MyService

public class MyService: CrudServiceBase<MyEntity>, IMyService
{
    private const string Folder = "MyEntity";

    private IFilesService filesService;

    public MyService(IDependencyResolver dependencyResolver) : base(dependencyResolver)
    {
        filesService = dependencyResolver.Resolve<IFilesService>();
    }
}

CrudServiceBase

public class CrudServiceBase<T> : ICrudService<T> where T : class
{
    private readonly IDependencyResolver dependencyResolver;
    protected DbContext dbContext => dependencyResolver.Resolve<DbContext>();

    public CrudServiceBase(IDependencyResolver dependencyResolver)
    {
        this.dependencyResolver = dependencyResolver;
    }

    public virtual async Task CreateAsync(T data)
    {
        var entity = await dbContext.Set<T>().AddAsync(data);
        await dbContext.SaveChangesAsync();
        entity.State = EntityState.Detached;
    }

    public virtual async Task DeleteAsync(T data)
    {
        var result = dbContext.Set<T>().Remove(data);
        await dbContext.SaveChangesAsync();
    }

    public virtual async Task<ICollection<T>> ReadAsync(
        List<Expression<Func<T, bool>>> filters = null,
        string orderByPropertyName = null, bool ascending = false)
    {
        var query = dbContext.Set<T>().Where(x => true);
        if (filters != null)
        {
            foreach (var filter in filters)
            {
                query = query.Where(filter);
            }
        }
        if (orderByPropertyName != null)
        {
            query = query.OrderByProperty(orderByPropertyName, ascending);
        }

        return query.AsNoTracking().ToList();
    }

    public virtual DbSet<T> GetDbSet()
        => dbContext.Set<T>();

    public virtual async Task UpdateAsync(T data)
    {
        var entity = dbContext.Set<T>().Update(data);
        await dbContext.SaveChangesAsync();
        entity.State = EntityState.Detached;
        //return entity;
    }

    public virtual async Task<ICollection<T>> ReadPaginatedAsync<TProp>(
        int page, int pageSize, int recordToTake,
        List<Expression<Func<T, bool>>> filters = null,
        string orderByPropertyName = null, bool ascending = false)
    {
        var query = dbContext.Set<T>().Where(x => true);
        if (filters != null)
            foreach (var filter in filters)
            {
                query = query.Where(filter);
            }

        if (orderByPropertyName != null)
        {
            query = query.OrderByProperty(orderByPropertyName, ascending);
        }
        return await query
            .Skip(pageSize * (page - 1))
            .Take(recordToTake)
            .AsNoTracking()
            .ToListAsync();
    }

    public virtual async Task<int> Count(List<Expression<Func<T, bool>>> filters = null)
    {

        var query = dbContext.Set<T>().Where(x => x != null);
        if (filters != null)
            foreach (var filter in filters)
            {
                query = query.Where(filter);
            }
        return await query.AsNoTracking().CountAsync();
    }
}

Если мы попробуем спам, refre sh поверх datatable, после некоторых попыток Custom Converter метод ParseParameter выдает Exception

Вторая операция началась в этом контексте до завершения предыдущей операции.

Что мы делаем не так? Что мы должны сделать, чтобы избежать этой проблемы?

Спасибо всем

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