Платформа Entity не обновляет свой кеш после обновления объекта в базе данныхC#

Место общения программистов C#
Anonymous
Платформа Entity не обновляет свой кеш после обновления объекта в базе данных

Сообщение Anonymous »

У меня есть проект .NET webapi, в котором есть объект «Категория», который имеет родительско-дочернюю связь сам с собой.
У меня созданы следующие родительско-дочерние отношения:
«Домашние животные»->»Домашнее животное Корм"->"Корм для собак"->"Уродливый корм для собак"
Я хочу удалить "Корм для собак", но сначала программно делаю "Корм для домашних животных" родительской категорией "Уродливая собака". Еда» так что «Уродливый корм для собак» не остался бесхозным.
Я успешно выполняю обновление, после чего вызывается вызов webapi для удаления «Корма для собак».
Когда я пытаюсь это сделать поэтому я получаю следующую ошибку:

Код: Выделить всё

DETAIL: Key (Id)=(0c6b1a97-d035-40ac-aa1f-ceef7144a236) is still referenced from table "Category".
at Npgsql.Internal.NpgsqlConnector.ReadMessageLong(Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
Exception data:
Severity: ERROR
SqlState: 23503
MessageText: update or delete on table "Category" violates foreign key constraint "FK_Category_Category_ParentId" on table "Category"
Detail: Key (Id)=(0c6b1a97-d035-40ac-aa1f-ceef7144a236) is still referenced from table "Category".
Но я проверяю базу данных, и «Уродливый корм для собак» был обновлен и теперь имеет ParentId «Корм для домашних животных», и ни одна другая запись категории в таблице не имеет идентификатора «Корм для собак». в качестве их ParentId, поэтому это должен быть кеш Entity Core.
Почему кеш не обновляется, когда я обновляю родительский идентификатор «Ugly Dog Food»?
Изображение

Вот мой класс CategoryService. Для обновления я вызываю здесь метод «UpdateCategory» с «Ugly Dog Food», а затем, после того как я получаю успешное обновление, я запускаю метод «DeleteCategory» для «Dog Food»:

Код: Выделить всё

using ShopBack.Database.Repositories;
using ShopBack.Database;

namespace ShopBack.Services;

public class CategoryService
{

private readonly ICategoryRepository _categoryRepository;
private readonly IShopUnitOfWork _unitOfWork;

public CategoryService(IShopUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
_categoryRepository = unitOfWork.Categories;
}

/// 
/// Call to create category in the CategoryRepository
/// 
/// 
The category entity
/// void
public async Task CreateCategory(Category category)
{
await _categoryRepository.AddAsync(category);
await _unitOfWork.SaveAsync();
}

/// 
/// Call to get all categories in the CategoryRepository
/// 
/// void
public async Task GetAllCategories()
{
return await _categoryRepository.GetAllAsync();
}

/// 
/// Call to get all categories in the CategoryRepository
/// 
/// void
public async Task GetAllTopCategories()
{
return await _categoryRepository.getAllTopLevelCategories();
}

/// 
/// Call to update Category in the CategoryRepository
/// 
/// The Category entity
/// void
public async Task UpdateCategory(Category category)
{
_categoryRepository.Update(category);
await _unitOfWork.SaveAsync();

}

/// 
/// Call to get a single Category in the CategoryRepository
/// 
/// The Category Id
/// Category
public async Task GetCategory(Guid categoryId)
{
return await _categoryRepository.GetByIdAsync(categoryId);
}

/// 
/// Call to delete Category in the CategoryRepository
/// 
/// The Category entity
/// void
public async Task DeleteCategory(Category category)
{
//todo what if the category has already been deleted? What happens?

_categoryRepository.Delete(category);
await _unitOfWork.SaveAsync();
}

}
Вот мой класс BaseRepository:

Код: Выделить всё

using Microsoft.EntityFrameworkCore;

namespace ShopBack.Database.Repositories
{
public class BaseRepository : IRepositoryBase where T : ModelBase
{
protected readonly LibraryContext _context;
public BaseRepository(LibraryContext context)
{
//context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
_context = context;
}
/// 
/// Gets all entities for this particular repository
/// 
public virtual async Task GetAllAsync()
{
return await _context.Set().ToListAsync();
}
/// 
/// Gets an entity by Id for this particular repository
/// 
public virtual async Task  GetByIdAsync(Guid id)
{
return await _context.Set().FindAsync(id);
}
/// 
/// Adds an an entity by for this particular repository
/// 
public virtual async Task AddAsync(T entity)
{
await _context.Set().AddAsync(entity);
}
/// 
/// Updates an entity by for this particular repository
/// 
public virtual void Update(T entity)
{
_context.Entry(entity).State = EntityState.Modified;
}
/// 
/// Deletes an entity for this particular repository
/// 
public virtual void Delete(T entity)
{
_context.Set().Remove(entity);
}
/// 
/// Checks to see if an entity exists for this particular repository
/// 
public virtual async Task ExistsAsync(Guid id)
{
return await _context.Set().AnyAsync(x => x.Id == id);
}
}
}
Вот мой класс UnitOfWork:

Код: Выделить всё

using ShopBack.Database.Repositories;

namespace ShopBack.Database
{
public class UnitOfWork : IUnitOfWork
{
private readonly LibraryContext _context;
private Dictionary _repositories;

/// 
///Constructor for our UnitOfWork class
/// 
public UnitOfWork(LibraryContext context)
{
_context = context;
_repositories = new Dictionary();
}

public void Dispose()
{
_context.Dispose();
}

TRepository IUnitOfWork.GetRepository()
{
var type = typeof(TEntity);

if (_repositories.ContainsKey(type))
{
return (TRepository)_repositories[type];
}
else
{
var repositoryType = typeof(TRepository);
var repGenType = repositoryType.MakeGenericType(typeof(TEntity));
var repositoryInstance = Activator.CreateInstance(repGenType, _context);

_repositories.Add(type, repositoryInstance);
}

return (TRepository)_repositories[type];
}

/// 
/// Persists our changes
/// 
public async Task SaveAsync()
{
await _context.SaveChangesAsync();
}
}
}
Разве кеш Entity Core Framework не должен был быть обновлен при обновлении, потому что я установил его состояние на «измененное», а затем запустил «SaveChangesAsync» в UnitOfWork?>

Подробнее здесь: https://stackoverflow.com/questions/791 ... e-database

Вернуться в «C#»