diff --git a/Persistence/Extensions/DbContextExtensions.cs b/Persistence/Extensions/DbContextExtensions.cs index e4009bd2..45cd52ae 100644 --- a/Persistence/Extensions/DbContextExtensions.cs +++ b/Persistence/Extensions/DbContextExtensions.cs @@ -15,10 +15,12 @@ public static IServiceCollection AddHaSpManContext( throw new ArgumentException("The value cannot be empty or whitespace.", nameof(connectionString)); } - serviceCollection.AddDbContextFactory(options => - options.UseSqlServer(connectionString, b => b + serviceCollection.AddDbContext( + options => options.UseSqlServer(connectionString, b => b .MigrationsAssembly("Persistence") - .MigrationsHistoryTable("__EFMigrationsHistory", "HaSpMan"))); + .MigrationsHistoryTable("__EFMigrationsHistory", "HaSpMan")), + ServiceLifetime.Transient); + return serviceCollection; } diff --git a/Persistence/Repositories/BankAccountRepository.cs b/Persistence/Repositories/BankAccountRepository.cs index 45d37cf1..7f3cbbc4 100644 --- a/Persistence/Repositories/BankAccountRepository.cs +++ b/Persistence/Repositories/BankAccountRepository.cs @@ -9,9 +9,9 @@ public class BankAccountRepository : IBankAccountRepository { private readonly HaSpManContext _context; - public BankAccountRepository(IDbContextFactory contextFactory) + public BankAccountRepository(HaSpManContext context) { - _context = contextFactory.CreateDbContext(); + _context = context ?? throw new ArgumentNullException(nameof(context)); } public void Add(BankAccount account) diff --git a/Persistence/Repositories/FinancialYearRepository.cs b/Persistence/Repositories/FinancialYearRepository.cs index 2e7e8e0a..0fb0fb66 100644 --- a/Persistence/Repositories/FinancialYearRepository.cs +++ b/Persistence/Repositories/FinancialYearRepository.cs @@ -10,10 +10,10 @@ public class FinancialYearRepository : IFinancialYearRepository private readonly HaSpManContext _context; - public FinancialYearRepository(IDbContextFactory contextFactory) + public FinancialYearRepository(HaSpManContext context) { - _context = contextFactory.CreateDbContext(); + _context = context; } public Task GetByIdAsync(Guid id, CancellationToken cancellationToken) diff --git a/Persistence/Repositories/MemberRepository.cs b/Persistence/Repositories/MemberRepository.cs index 0cce1b75..91c6fa94 100644 --- a/Persistence/Repositories/MemberRepository.cs +++ b/Persistence/Repositories/MemberRepository.cs @@ -9,10 +9,10 @@ public class MemberRepository : IMemberRepository { private readonly HaSpManContext _context; - public MemberRepository(IDbContextFactory contextFactory) + public MemberRepository(HaSpManContext context) { - _context = contextFactory.CreateDbContext(); + _context = context; } public void Add(Member member) { diff --git a/Queries/BankAccounts/GetBankAccountById.cs b/Queries/BankAccounts/GetBankAccountById.cs index fa6710f6..6d7f965d 100644 --- a/Queries/BankAccounts/GetBankAccountById.cs +++ b/Queries/BankAccounts/GetBankAccountById.cs @@ -1,3 +1,5 @@ +using AutoMapper.QueryableExtensions; + using Microsoft.EntityFrameworkCore; using Persistence; @@ -9,19 +11,17 @@ public record GetBankAccountByIdQuery(Guid Id) : IRequest; public class GetBankAccountByIdHandler : IRequestHandler { private readonly IMapper _mapper; - private readonly IDbContextFactory _contextFactory; + private readonly HaSpManContext _context; - public GetBankAccountByIdHandler(IMapper mapper, IDbContextFactory contextFactory) + public GetBankAccountByIdHandler(IMapper mapper, HaSpManContext context) { - _mapper = mapper; - _contextFactory = contextFactory; + _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper)); + _context = context ?? throw new ArgumentNullException(nameof(context)); } - public async Task Handle(GetBankAccountByIdQuery request, CancellationToken cancellationToken) - { - var context = await _contextFactory.CreateDbContextAsync(cancellationToken); - var bankAccount = await context.BankAccounts.SingleAsync(b => b.Id == request.Id, cancellationToken: cancellationToken); - - return _mapper.Map(bankAccount); - } + public Task Handle(GetBankAccountByIdQuery request, CancellationToken cancellationToken) + => _context.BankAccounts + .Where(b => b.Id == request.Id) + .ProjectTo(_mapper.ConfigurationProvider) + .SingleAsync(cancellationToken); } \ No newline at end of file diff --git a/Queries/BankAccounts/SearchBankAccounts.cs b/Queries/BankAccounts/SearchBankAccounts.cs index be568111..0414acab 100644 --- a/Queries/BankAccounts/SearchBankAccounts.cs +++ b/Queries/BankAccounts/SearchBankAccounts.cs @@ -28,19 +28,18 @@ public enum BankAccountDetailOrderOption public class SearchBankAccountsHandler : IRequestHandler> { - private readonly IDbContextFactory _contextFactory; + private readonly HaSpManContext _context; private readonly IMapper _mapper; - public SearchBankAccountsHandler(IDbContextFactory contextFactory, IMapper mapper) + public SearchBankAccountsHandler(HaSpManContext context, IMapper mapper) { - _contextFactory = contextFactory; - _mapper = mapper; + _context = context ?? throw new ArgumentNullException(nameof(context)); + _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper)); } public async Task> Handle(SearchBankAccountsQuery request, CancellationToken cancellationToken) { - var context = await _contextFactory.CreateDbContextAsync(cancellationToken); - var bankAccountsQueryable = context.BankAccounts + var bankAccountsQueryable = _context.BankAccounts .AsNoTracking() .Where(GetFilterCriteria(request.SearchString)); diff --git a/Queries/FinancialYears/GetFinancialYearsQuery.cs b/Queries/FinancialYears/GetFinancialYearsQuery.cs index cc522593..5a6317b3 100644 --- a/Queries/FinancialYears/GetFinancialYearsQuery.cs +++ b/Queries/FinancialYears/GetFinancialYearsQuery.cs @@ -8,22 +8,19 @@ public record GetFinancialYearsQuery() : IRequest>; public class GetFinancialYearsHandler : IRequestHandler> { - private readonly IDbContextFactory _contextFactory; + private readonly HaSpManContext _context; - public GetFinancialYearsHandler(IDbContextFactory contextFactory) + public GetFinancialYearsHandler(HaSpManContext context) { - _contextFactory = contextFactory; + _context = context ?? throw new ArgumentNullException(nameof(context)); } - + public async Task> Handle(GetFinancialYearsQuery request, CancellationToken cancellationToken) { - var context = await _contextFactory.CreateDbContextAsync(cancellationToken); - var financialYears = await context.FinancialYears.ToListAsync(cancellationToken); - - return financialYears + return await _context.FinancialYears .OrderByDescending(x => x.StartDate) .Select(x => new FinancialYear(x.Id, x.StartDate, x.EndDate, x.IsClosed, x.Name)) - .ToList(); + .ToListAsync(cancellationToken); } } \ No newline at end of file diff --git a/Queries/Members/Handlers/AutocompleteMember/AutocompleteCounterpartyHandler.cs b/Queries/Members/Handlers/AutocompleteMember/AutocompleteCounterpartyHandler.cs index 098947cd..aa35c8aa 100644 --- a/Queries/Members/Handlers/AutocompleteMember/AutocompleteCounterpartyHandler.cs +++ b/Queries/Members/Handlers/AutocompleteMember/AutocompleteCounterpartyHandler.cs @@ -6,19 +6,17 @@ namespace Queries.Members.Handlers.AutocompleteMember; public class AutocompleteCounterpartyHandler : IRequestHandler { - private readonly IDbContextFactory _contextFactory; + private readonly HaSpManContext _context; - public AutocompleteCounterpartyHandler(IDbContextFactory contextFactory) + public AutocompleteCounterpartyHandler(HaSpManContext context) { - _contextFactory = contextFactory; + _context = context ?? throw new ArgumentNullException(nameof(context)); } public async Task Handle(AutocompleteCounterpartyQuery request, CancellationToken cancellationToken) { - var context = await _contextFactory.CreateDbContextAsync(cancellationToken); - if (request.IsMemberSearch) { - var members = await context.Members + var members = await _context.Members .Where(x => x.FirstName.ToLower().Contains(request.SearchString.ToLower()) || x.LastName.ToLower().Contains(request.SearchString.ToLower())) @@ -27,7 +25,7 @@ public async Task Handle(AutocompleteCounterpa return new AutocompleteCounterpartyResponse(members); } - var counterParties = await context.FinancialYears + var counterParties = await _context.FinancialYears .SelectMany(x => x.Transactions) .AsNoTracking() .Where(x => diff --git a/Queries/Members/Handlers/GetBankAccountInfos/GetBankAccountInfosHandler.cs b/Queries/Members/Handlers/GetBankAccountInfos/GetBankAccountInfosHandler.cs index 0dad98b0..8fb8c6d6 100644 --- a/Queries/Members/Handlers/GetBankAccountInfos/GetBankAccountInfosHandler.cs +++ b/Queries/Members/Handlers/GetBankAccountInfos/GetBankAccountInfosHandler.cs @@ -6,20 +6,16 @@ namespace Queries.Members.Handlers.GetBankAccountInfos; public class GetBankAccountInfosHandler : IRequestHandler> { - private readonly IDbContextFactory _contextFactory; + private readonly HaSpManContext _context; - public GetBankAccountInfosHandler(IDbContextFactory contextFactory) + public GetBankAccountInfosHandler(HaSpManContext context) { - _contextFactory = contextFactory; + _context = context ?? throw new ArgumentNullException(nameof(context)); } public async Task> Handle(GetBankAccountInfos request, CancellationToken cancellationToken) - { - await using var context = _contextFactory.CreateDbContext(); - return await context.BankAccounts + => await _context.BankAccounts .AsNoTracking() .Select(x => new BankAccountInfo(x.Id, x.Name)) .ToListAsync(cancellationToken); - - } } diff --git a/Queries/Members/Handlers/GetMemberById/GetMemberByIdHandler.cs b/Queries/Members/Handlers/GetMemberById/GetMemberByIdHandler.cs index 0e1217d0..ab2b588f 100644 --- a/Queries/Members/Handlers/GetMemberById/GetMemberByIdHandler.cs +++ b/Queries/Members/Handlers/GetMemberById/GetMemberByIdHandler.cs @@ -1,3 +1,5 @@ +using AutoMapper.QueryableExtensions; + using Microsoft.EntityFrameworkCore; using Persistence; @@ -9,19 +11,17 @@ namespace Queries.Members.Handlers.GetMemberById; public class GetMemberByIdHandler : IRequestHandler { private readonly IMapper _mapper; - private readonly IDbContextFactory _contextFactory; + private readonly HaSpManContext _context; - public GetMemberByIdHandler(IMapper mapper, IDbContextFactory contextFactory) + public GetMemberByIdHandler(IMapper mapper, HaSpManContext context) { - _mapper = mapper; - _contextFactory = contextFactory; + _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper)); + _context = context ?? throw new ArgumentNullException(nameof(context)); } - public async Task Handle(GetMemberByIdQuery request, CancellationToken cancellationToken) - { - var context = _contextFactory.CreateDbContext(); - var member = await context.Members.SingleAsync(m => m.Id == request.Id, cancellationToken: cancellationToken); - - return _mapper.Map(member); - } + public Task Handle(GetMemberByIdQuery request, CancellationToken cancellationToken) + => _context.Members + .Where(m => m.Id == request.Id) + .ProjectTo(_mapper.ConfigurationProvider) + .SingleAsync(cancellationToken); } diff --git a/Queries/Members/Handlers/SearchMembers/SearchMembersHandler.cs b/Queries/Members/Handlers/SearchMembers/SearchMembersHandler.cs index d988dc4d..beba99e6 100644 --- a/Queries/Members/Handlers/SearchMembers/SearchMembersHandler.cs +++ b/Queries/Members/Handlers/SearchMembers/SearchMembersHandler.cs @@ -13,18 +13,16 @@ namespace Queries.Members.Handlers.SearchMembers; public class SearchMembersHandler : IRequestHandler> { - private readonly IDbContextFactory _contextFactory; + private readonly HaSpManContext _context; - public SearchMembersHandler(IDbContextFactory contextFactory) + public SearchMembersHandler(HaSpManContext context) { - _contextFactory = contextFactory; + _context = context ?? throw new ArgumentNullException(nameof(context)); } public async Task> Handle(SearchMembersQuery request, CancellationToken cancellationToken) { - var context = await _contextFactory.CreateDbContextAsync(cancellationToken); - var memberQueryable = context.Members - + var memberQueryable = _context.Members .AsNoTracking() .Where(GetTextFilterCriteria(request.SearchString)); diff --git a/Queries/Members/MemberExistsByEmailQuery.cs b/Queries/Members/MemberExistsByEmailQuery.cs index 4ee38ac6..2608be5f 100644 --- a/Queries/Members/MemberExistsByEmailQuery.cs +++ b/Queries/Members/MemberExistsByEmailQuery.cs @@ -12,18 +12,16 @@ public record MemberExistsByEmailQuery(string EmailAddress, Guid? ExcludeId = nu public class MemberExistsByEmail : IRequestHandler { - private readonly HaSpManContext _dbContext; + private readonly HaSpManContext _context; - public MemberExistsByEmail(IDbContextFactory dbContextFactory) + public MemberExistsByEmail(HaSpManContext context) { - _dbContext = dbContextFactory.CreateDbContext(); + _context = context ?? throw new ArgumentNullException(nameof(context)); } public Task Handle(MemberExistsByEmailQuery request, CancellationToken cancellationToken) { - return _dbContext.Members - .AsNoTracking() - .AnyAsync(BuildQueryPredicate(request), cancellationToken); + return _context.Members.AnyAsync(BuildQueryPredicate(request), cancellationToken); } private static Expression> BuildQueryPredicate(MemberExistsByEmailQuery request) => request.ExcludeId is null diff --git a/Queries/Members/MemberExistsByNameAndAddressQuery.cs b/Queries/Members/MemberExistsByNameAndAddressQuery.cs index 1e67d431..8174c4a1 100644 --- a/Queries/Members/MemberExistsByNameAndAddressQuery.cs +++ b/Queries/Members/MemberExistsByNameAndAddressQuery.cs @@ -22,9 +22,9 @@ public class MemberExistsByNameAndAddress : IRequestHandler dbContextFactory) + public MemberExistsByNameAndAddress(HaSpManContext dbContext) { - _dbContext = dbContextFactory.CreateDbContext(); + _dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext)); } public Task Handle(MemberExistsByNameAndAddressQuery request, CancellationToken cancellationToken) diff --git a/Queries/Transactions/GetAttachment/GetAttachmentCommand.cs b/Queries/Transactions/GetAttachment/GetAttachmentCommand.cs index 27ae0cc7..11ed3c40 100644 --- a/Queries/Transactions/GetAttachment/GetAttachmentCommand.cs +++ b/Queries/Transactions/GetAttachment/GetAttachmentCommand.cs @@ -12,20 +12,19 @@ public record GetAttachmentQuery(Guid TransactionId, string FileName) : IRequest public class GetAttachmentHandler : IRequestHandler { - private readonly IDbContextFactory _dbContextFactory; + private readonly HaSpManContext _dbContext; private readonly IAttachmentStorage _attachmentStorage; - public GetAttachmentHandler(IDbContextFactory dbContextFactory, IAttachmentStorage attachmentStorage) + public GetAttachmentHandler(HaSpManContext dbContext, IAttachmentStorage attachmentStorage) { - _dbContextFactory = dbContextFactory; - _attachmentStorage = attachmentStorage; + _dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext)); + _attachmentStorage = attachmentStorage ?? throw new ArgumentNullException(nameof(attachmentStorage)); } public async Task Handle(GetAttachmentQuery request, CancellationToken cancellationToken) { - var context = await _dbContextFactory.CreateDbContextAsync(cancellationToken); var transactionId = request.TransactionId; var transaction = - await context.FinancialYears + await _dbContext.FinancialYears .SelectMany(x => x.Transactions) .AsNoTracking() .SingleOrDefaultAsync(x => x.Id == transactionId, cancellationToken) diff --git a/Queries/Transactions/Handlers/GetTransactionByIdHandler.cs b/Queries/Transactions/Handlers/GetTransactionByIdHandler.cs index aa265d9a..0fef3a75 100644 --- a/Queries/Transactions/Handlers/GetTransactionByIdHandler.cs +++ b/Queries/Transactions/Handlers/GetTransactionByIdHandler.cs @@ -1,4 +1,6 @@ -using Microsoft.EntityFrameworkCore; +using AutoMapper.QueryableExtensions; + +using Microsoft.EntityFrameworkCore; using Persistence; @@ -8,21 +10,18 @@ namespace Queries.Transactions.Handlers; public class GetTransactionByIdHandler : IRequestHandler { - private readonly IDbContextFactory _contextFactory; + private readonly HaSpManContext _dbContext; private readonly IMapper _mapper; - public GetTransactionByIdHandler(IDbContextFactory contextFactory, IMapper mapper) + public GetTransactionByIdHandler(HaSpManContext dbContext, IMapper mapper) { - _contextFactory = contextFactory; - _mapper = mapper; + _dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext)); + _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper)); } - public async Task Handle(GetTransactionByIdQuery request, CancellationToken cancellationToken) - { - var context = await _contextFactory.CreateDbContextAsync(cancellationToken); - var transaction = await context.FinancialYears + public Task Handle(GetTransactionByIdQuery request, CancellationToken cancellationToken) + => _dbContext.FinancialYears .SelectMany(x => x.Transactions) - .AsNoTracking().SingleAsync(x => x.Id == request.Id, cancellationToken); - - return _mapper.Map(transaction); - } + .Where(x => x.Id == request.Id) + .ProjectTo(_mapper.ConfigurationProvider) + .SingleAsync(cancellationToken); } diff --git a/Queries/Transactions/Handlers/GetTransactionsHandler.cs b/Queries/Transactions/Handlers/GetTransactionsHandler.cs index ce3cb3ed..2088e1c8 100644 --- a/Queries/Transactions/Handlers/GetTransactionsHandler.cs +++ b/Queries/Transactions/Handlers/GetTransactionsHandler.cs @@ -15,20 +15,18 @@ namespace Queries.Transactions.Handlers; public class GetTransactionsHandler : IRequestHandler> { - private readonly IDbContextFactory _contextFactory; + private readonly HaSpManContext _dbContext; private readonly IMapper _mapper; - public GetTransactionsHandler(IDbContextFactory contextFactory, IMapper mapper) + public GetTransactionsHandler(HaSpManContext dbContext, IMapper mapper) { - _contextFactory = contextFactory; - _mapper = mapper; + _dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext)); + _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper)); } public async Task> Handle(GetTransactionQuery request, CancellationToken cancellationToken) { - var context = await _contextFactory.CreateDbContextAsync(cancellationToken); - - var baseQuery = context.FinancialYears + var baseQuery = _dbContext.FinancialYears .AsNoTracking() .SelectMany(y => y.Transactions) .Where(GetFilterCriteria(request.SearchString)); diff --git a/Web/Pages/Transactions/TransactionForm.razor.cs b/Web/Pages/Transactions/TransactionForm.razor.cs index edfbbf4a..5b10e179 100644 --- a/Web/Pages/Transactions/TransactionForm.razor.cs +++ b/Web/Pages/Transactions/TransactionForm.razor.cs @@ -243,6 +243,7 @@ private async Task TrySetFinancialYearId() ?? throw new Exception($"Couldn't get financial year id for transaction with id {Transaction.Id}"); Transaction.FinancialYearId = financialYear.Id; + await Task.Delay(1000); } private async Task SetFinancialYears()