В настоящее время я создаю тестовое приложение с компонентами Razor, Entity Framework Core и несколькими стандартными шаблонами (Repository Pattern, UnitOfWork). Изменения в моих сущностях временно сохраняются (если я перемещаюсь по страницам, изменения видны) без вызова SaveChanges
в моем классе UoW (неправильно). Обновление приложения удаляет эти временные. изменения - вызов моей единицы работы Complete()
функция сохраняет измененные данные постоянно (справа).
Я не могу понять, почему эти временные изменения объекта используются / видны на моих страницах. Единица работы (в общем) работает, потому что только вызов SaveChanges()
сохраняет данные для времени выполнения моего приложения). Текущая настройка:
- VS 2019 Preview
- .NET Core v3.0.0-preview2 (поскольку предварительный просмотр 3 не работает в сочетании с Windows 7 и компонентами Razor, проблема уже указана на GitHub)
Startup.cs - добавление единицы работы при запуске моего сервера
services.AddScoped<IUnitOfWork, UnitOfWork>();
и добавление контекста базы данных в памяти
services.AddDbContext<DatabaseContext>(options => options.UseInMemoryDatabase("Database"));
DatabaseContext.cs
public class DatabaseContext : DbContext
{
public DbSet<Customer> Customers { get; set; }
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Customer>(ConfigureCustomer);
}
private void ConfigureCustomer(EntityTypeBuilder<Customer> builder)
{
builder.ToTable("Customers");
builder.HasKey(c => c.Id);
builder.Property(c => c.Id).IsRequired();
}
}
Repository.cs - реализация репозитория
public class Repository<T> : IRepository<T> where T : class
{
protected readonly DbContext Context;
public Repository(DbContext context)
{
Context = context;
}
public void Add(T entity)
{
Context.Set<T>().AddAsync(entity);
}
public void AddRange(IEnumerable<T> entities)
{
Context.Set<T>().AddRange(entities);
}
public async Task<IEnumerable<T>> FindAsync(Expression<Func<T, bool>> predicate)
{
return await Context.Set<T>().Where(predicate).ToListAsync();
}
public async Task<T> GetAsync(int id)
{
return await Context.Set<T>().FindAsync(id);
}
public async Task<IEnumerable<T>> GetAllAsync()
{
return await Context.Set<T>().ToListAsync();
}
public void Remove(T entity)
{
Context.Set<T>().Remove(entity);
}
public void RemoveRange(IEnumerable<T> entities)
{
Context.Set<T>().RemoveRange(entities);
}
public void Update(T entity)
{
Context.Set<T>().Update(entity);
}
}
CustomersRepository.cs
public class CustomersRepository : Repository<Customer>, ICustomersRepository
{
public CustomersRepository(DatabaseContext context) : base(context)
{
}
}
Реализация UnitOfWork
public class UnitOfWork : IUnitOfWork
{
public ICustomersRepository Customers { get; private set; }
private readonly DatabaseContext _context;
public UnitOfWork(DatabaseContext context)
{
_context = context;
Customers = new CustomersRepository(_context);
}
public async Task<int> CompleteAsync()
{
return await _context.SaveChangesAsync();
}
public void Dispose()
{
_context.Dispose();
}
}
Моя клиентская сущность
public class Customer
{
public int Id { get; set; }
public string Firstname { get; set; }
}
Моя страница с подробностями теста
@page "/customers/{CustomerId:int}"
@using RazorApp.Core.Entities
@using RazorApp.Core.Interfaces
@inject IUnitOfWork UnitOfWork
<h1>Customer details</h1>
@if (customer == null)
{
<p>Loading ...</p>
}
else
{
<div class="card">
<div class="card-body">
<div class="card-text">
<div class="form-group">
<label>Id</label>
<input type="text" class="form-control" value="@customer.Id" disabled />
</div>
<div class="form-group">
<label>Firstname</label>
<input type="text" class="form-control" value="@customer.Firstname" bind="customer.Firstname" />
</div>
<button class="btn btn-primary" onclick="@UpdateCustomer">Save</button>
</div>
</div>
</div>
}
@functions {
[Parameter] int CustomerId { get; set; } = 0;
Customer customer = null;
protected override async Task OnInitAsync()
{
await LoadCustomer(CustomerId);
}
protected async Task LoadCustomer(int customerId)
{
customer = null;
customer = await UnitOfWork.Customers.GetAsync(customerId);
}
protected async void UpdateCustomer()
{
UnitOfWork.Customers.Update(customer);
await UnitOfWork.CompleteAsync();
}
}
Я ожидаю, что изменения в объекте (с привязками данных или просто регулярными изменениями, такими как customer.Firstname = "123"
) должны сохраняться только при вызове моей функции UoW Complete
. Я не хочу, чтобы в моем приложении обновлялись объекты «кэшированные / временные / ссылочные».