Я видел много вопросов и ответов об этой 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
Вторая операция началась в этом контексте до завершения предыдущей операции.
Что мы делаем не так? Что мы должны сделать, чтобы избежать этой проблемы?
Спасибо всем