Razor Components + EF Core + Репозиторий / UoW Pattern изменяет сущности без SaveChanges () - PullRequest
0 голосов
/ 01 апреля 2019

В настоящее время я создаю тестовое приложение с компонентами 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. Я не хочу, чтобы в моем приложении обновлялись объекты «кэшированные / временные / ссылочные».

...