Skip to content
This repository has been archived by the owner on May 23, 2024. It is now read-only.

Commit

Permalink
replace counter by specific query to avoid load each items in memory (#…
Browse files Browse the repository at this point in the history
…611)

* replace counter by specific query to avoid load each items in memory

* Create IBasketQueryService
  • Loading branch information
michelcedric authored Nov 2, 2021
1 parent 553a101 commit 64f150d
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 129 deletions.
9 changes: 9 additions & 0 deletions src/ApplicationCore/Interfaces/IBasketQueryService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Threading.Tasks;

namespace Microsoft.eShopWeb.ApplicationCore.Interfaces
{
public interface IBasketQueryService
{
Task<int> CountTotalBasketItems(string username);
}
}
11 changes: 0 additions & 11 deletions src/ApplicationCore/Interfaces/IOrderRepository.cs

This file was deleted.

27 changes: 27 additions & 0 deletions src/Infrastructure/Data/BasketQueryService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
using System.Linq;
using System.Threading.Tasks;

namespace Microsoft.eShopWeb.Infrastructure.Data
{
public class BasketQueryService : IBasketQueryService
{
private readonly CatalogContext _dbContext;

public BasketQueryService(CatalogContext dbContext)
{
_dbContext = dbContext;
}

public async Task<int> CountTotalBasketItems(string username)
{
var totalItems = await _dbContext.Baskets
.Where(basket => basket.BuyerId == username)
.SelectMany(item => item.Items)
.SumAsync(sum => sum.Quantity);

return totalItems;
}
}
}
90 changes: 4 additions & 86 deletions src/Infrastructure/Data/EfRepository.cs
Original file line number Diff line number Diff line change
@@ -1,94 +1,12 @@
using Ardalis.Specification;
using Ardalis.Specification.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.eShopWeb.ApplicationCore.Entities;
using Ardalis.Specification.EntityFrameworkCore;
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.eShopWeb.Infrastructure.Data
{
public class EfRepository<T> : RepositoryBase<T>, IReadRepository<T>, IRepository<T> where T : class, IAggregateRoot
{
public EfRepository(CatalogContext dbContext) : base(dbContext)
{
public EfRepository(CatalogContext dbContext) : base(dbContext)
{
}
}
}
/// <summary>
/// "There's some repetition here - couldn't we have some the sync methods call the async?"
/// https://blogs.msdn.microsoft.com/pfxteam/2012/04/13/should-i-expose-synchronous-wrappers-for-asynchronous-methods/
/// </summary>
/// <typeparam name="T"></typeparam>
// public class EfRepository<T> : IAsyncRepository<T> where T : BaseEntity, IAggregateRoot
// {
// protected readonly CatalogContext _dbContext;

// public EfRepository(CatalogContext dbContext)
// {
// _dbContext = dbContext;
// }

// public virtual async Task<T> GetByIdAsync(int id, CancellationToken cancellationToken = default)
// {
// var keyValues = new object[] { id };
// return await _dbContext.Set<T>().FindAsync(keyValues, cancellationToken);
// }

// public async Task<IReadOnlyList<T>> ListAllAsync(CancellationToken cancellationToken = default)
// {
// return await _dbContext.Set<T>().ToListAsync(cancellationToken);
// }

// public async Task<IReadOnlyList<T>> ListAsync(ISpecification<T> spec, CancellationToken cancellationToken = default)
// {
// var specificationResult = ApplySpecification(spec);
// return await specificationResult.ToListAsync(cancellationToken);
// }

// public async Task<int> CountAsync(ISpecification<T> spec, CancellationToken cancellationToken = default)
// {
// var specificationResult = ApplySpecification(spec);
// return await specificationResult.CountAsync(cancellationToken);
// }

// public async Task<T> AddAsync(T entity, CancellationToken cancellationToken = default)
// {
// await _dbContext.Set<T>().AddAsync(entity, cancellationToken);
// await _dbContext.SaveChangesAsync(cancellationToken);

// return entity;
// }

// public async Task UpdateAsync(T entity, CancellationToken cancellationToken = default)
// {
// _dbContext.Entry(entity).State = EntityState.Modified;
// await _dbContext.SaveChangesAsync(cancellationToken);
// }

// public async Task DeleteAsync(T entity, CancellationToken cancellationToken = default)
// {
// _dbContext.Set<T>().Remove(entity);
// await _dbContext.SaveChangesAsync(cancellationToken);
// }

// public async Task<T> FirstAsync(ISpecification<T> spec, CancellationToken cancellationToken = default)
// {
// var specificationResult = ApplySpecification(spec);
// return await specificationResult.FirstAsync(cancellationToken);
// }

// public async Task<T> FirstOrDefaultAsync(ISpecification<T> spec, CancellationToken cancellationToken = default)
// {
// var specificationResult = ApplySpecification(spec);
// return await specificationResult.FirstOrDefaultAsync(cancellationToken);
// }

// private IQueryable<T> ApplySpecification(ISpecification<T> spec)
// {
// var evaluator = new SpecificationEvaluator<T>();
// return evaluator.GetQuery(_dbContext.Set<T>().AsQueryable(), spec);
// }
// }
}
22 changes: 0 additions & 22 deletions src/Infrastructure/Data/OrderRepository.cs

This file was deleted.

3 changes: 1 addition & 2 deletions src/Web/Configuration/ConfigureCoreServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@ public static class ConfigureCoreServices
public static IServiceCollection AddCoreServices(this IServiceCollection services,
IConfiguration configuration)
{
//services.AddScoped(typeof(IAsyncRepository<>), typeof(EfRepository<>));
services.AddScoped(typeof(IReadRepository<>), typeof(EfRepository<>));
services.AddScoped(typeof(IRepository<>), typeof(EfRepository<>));

services.AddScoped<IBasketService, BasketService>();
services.AddScoped<IOrderService, OrderService>();
//services.AddScoped<IOrderRepository, OrderRepository>();
services.AddScoped<IBasketQueryService, BasketQueryService>();
services.AddSingleton<IUriComposer>(new UriComposer(configuration.Get<CatalogSettings>()));
services.AddScoped(typeof(IAppLogger<>), typeof(LoggerAdapter<>));
services.AddTransient<IEmailSender, EmailSender>();
Expand Down
17 changes: 9 additions & 8 deletions src/Web/Services/BasketViewModelService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,17 @@ public class BasketViewModelService : IBasketViewModelService
{
private readonly IRepository<Basket> _basketRepository;
private readonly IUriComposer _uriComposer;
private readonly IBasketQueryService _basketQueryService;
private readonly IRepository<CatalogItem> _itemRepository;

public BasketViewModelService(IRepository<Basket> basketRepository,
IRepository<CatalogItem> itemRepository,
IUriComposer uriComposer)
IUriComposer uriComposer,
IBasketQueryService basketQueryService)
{
_basketRepository = basketRepository;
_uriComposer = uriComposer;
_basketQueryService = basketQueryService;
_itemRepository = itemRepository;
}

Expand All @@ -36,7 +39,7 @@ public async Task<BasketViewModel> GetOrCreateBasketForUser(string userName)
}
var viewModel = await Map(basket);
return viewModel;
}
}

private async Task<BasketViewModel> CreateBasketForUser(string userId)
{
Expand Down Expand Up @@ -79,18 +82,16 @@ public async Task<BasketViewModel> Map(Basket basket)
return new BasketViewModel()
{
BuyerId = basket.BuyerId,
Id = basket.Id,
Id = basket.Id,
Items = await GetBasketItems(basket.Items)
};
}

public async Task<int> CountTotalBasketItems(string username)
{
var basketSpec = new BasketWithItemsSpecification(username);
var basket = await _basketRepository.GetBySpecAsync(basketSpec);
if (basket == null)
return 0;
return basket.Items.Sum(i => i.Quantity);
var counter = await _basketQueryService.CountTotalBasketItems(username);

return counter;
}
}
}

0 comments on commit 64f150d

Please sign in to comment.