Initial Upgrade to .NET Core 2.0 (#50)
* Ardalis/upgrade1 (#44) * Upgrading to netcore 2.0 Updating repository to support async options and refactoring to use it. * Starting work on tracking customer orders feature. * Cleaning up some bugs Working on basket view component implementation * Fixing up styles, especially for basket in header. * Adding Order Features (#47) * Working on order model binding from checkout page - WIP * Small layout tweaks (#43) * Updating quantities implemented. * Fixed basket widget count * Order History (#49) * working on creating and viewing orders. * Working on wiring up listing of orders * List orders page works as expected. Needed to support ThenInclude scenarios. Currently using strings.
This commit is contained in:
@@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using Microsoft.eShopWeb.ApplicationCore.Entities;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using ApplicationCore.Entities.OrderAggregate;
|
||||
|
||||
namespace Infrastructure.Data
|
||||
{
|
||||
@@ -20,6 +21,8 @@ namespace Infrastructure.Data
|
||||
public DbSet<CatalogItem> CatalogItems { get; set; }
|
||||
public DbSet<CatalogBrand> CatalogBrands { get; set; }
|
||||
public DbSet<CatalogType> CatalogTypes { get; set; }
|
||||
public DbSet<Order> Orders { get; set; }
|
||||
public DbSet<OrderItem> OrderItems { get; set; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
@@ -27,6 +30,8 @@ namespace Infrastructure.Data
|
||||
builder.Entity<CatalogBrand>(ConfigureCatalogBrand);
|
||||
builder.Entity<CatalogType>(ConfigureCatalogType);
|
||||
builder.Entity<CatalogItem>(ConfigureCatalogItem);
|
||||
builder.Entity<Order>(ConfigureOrder);
|
||||
builder.Entity<OrderItem>(ConfigureOrderItem);
|
||||
}
|
||||
|
||||
private void ConfigureBasket(EntityTypeBuilder<Basket> builder)
|
||||
@@ -36,7 +41,7 @@ namespace Infrastructure.Data
|
||||
navigation.SetPropertyAccessMode(PropertyAccessMode.Field);
|
||||
}
|
||||
|
||||
void ConfigureCatalogItem(EntityTypeBuilder<CatalogItem> builder)
|
||||
private void ConfigureCatalogItem(EntityTypeBuilder<CatalogItem> builder)
|
||||
{
|
||||
builder.ToTable("Catalog");
|
||||
|
||||
@@ -63,7 +68,7 @@ namespace Infrastructure.Data
|
||||
.HasForeignKey(ci => ci.CatalogTypeId);
|
||||
}
|
||||
|
||||
void ConfigureCatalogBrand(EntityTypeBuilder<CatalogBrand> builder)
|
||||
private void ConfigureCatalogBrand(EntityTypeBuilder<CatalogBrand> builder)
|
||||
{
|
||||
builder.ToTable("CatalogBrand");
|
||||
|
||||
@@ -78,7 +83,7 @@ namespace Infrastructure.Data
|
||||
.HasMaxLength(100);
|
||||
}
|
||||
|
||||
void ConfigureCatalogType(EntityTypeBuilder<CatalogType> builder)
|
||||
private void ConfigureCatalogType(EntityTypeBuilder<CatalogType> builder)
|
||||
{
|
||||
builder.ToTable("CatalogType");
|
||||
|
||||
@@ -92,5 +97,14 @@ namespace Infrastructure.Data
|
||||
.IsRequired()
|
||||
.HasMaxLength(100);
|
||||
}
|
||||
private void ConfigureOrder(EntityTypeBuilder<Order> builder)
|
||||
{
|
||||
builder.OwnsOne(o => o.ShipToAddress);
|
||||
}
|
||||
private void ConfigureOrderItem(EntityTypeBuilder<OrderItem> builder)
|
||||
{
|
||||
builder.OwnsOne(i => i.ItemOrdered);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,39 +10,38 @@ namespace Infrastructure.Data
|
||||
{
|
||||
public class CatalogContextSeed
|
||||
{
|
||||
public static async Task SeedAsync(IApplicationBuilder applicationBuilder, ILoggerFactory loggerFactory, int? retry = 0)
|
||||
public static async Task SeedAsync(IApplicationBuilder applicationBuilder,
|
||||
CatalogContext catalogContext,
|
||||
ILoggerFactory loggerFactory, int? retry = 0)
|
||||
{
|
||||
int retryForAvailability = retry.Value;
|
||||
try
|
||||
{
|
||||
var context = (CatalogContext)applicationBuilder
|
||||
.ApplicationServices.GetService(typeof(CatalogContext));
|
||||
|
||||
// TODO: Only run this if using a real database
|
||||
// context.Database.Migrate();
|
||||
|
||||
if (!context.CatalogBrands.Any())
|
||||
if (!catalogContext.CatalogBrands.Any())
|
||||
{
|
||||
context.CatalogBrands.AddRange(
|
||||
catalogContext.CatalogBrands.AddRange(
|
||||
GetPreconfiguredCatalogBrands());
|
||||
|
||||
await context.SaveChangesAsync();
|
||||
await catalogContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
if (!context.CatalogTypes.Any())
|
||||
if (!catalogContext.CatalogTypes.Any())
|
||||
{
|
||||
context.CatalogTypes.AddRange(
|
||||
catalogContext.CatalogTypes.AddRange(
|
||||
GetPreconfiguredCatalogTypes());
|
||||
|
||||
await context.SaveChangesAsync();
|
||||
await catalogContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
if (!context.CatalogItems.Any())
|
||||
if (!catalogContext.CatalogItems.Any())
|
||||
{
|
||||
context.CatalogItems.AddRange(
|
||||
catalogContext.CatalogItems.AddRange(
|
||||
GetPreconfiguredItems());
|
||||
|
||||
await context.SaveChangesAsync();
|
||||
await catalogContext.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -50,9 +49,9 @@ namespace Infrastructure.Data
|
||||
if (retryForAvailability < 10)
|
||||
{
|
||||
retryForAvailability++;
|
||||
var log = loggerFactory.CreateLogger("catalog seed");
|
||||
var log = loggerFactory.CreateLogger<CatalogContextSeed>();
|
||||
log.LogError(ex.Message);
|
||||
await SeedAsync(applicationBuilder, loggerFactory, retryForAvailability);
|
||||
await SeedAsync(applicationBuilder, catalogContext, loggerFactory, retryForAvailability);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,36 +3,68 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.eShopWeb.ApplicationCore.Entities;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Infrastructure.Data
|
||||
{
|
||||
public class EfRepository<T> : IRepository<T> where T : BaseEntity
|
||||
/// <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> : IRepository<T>, IAsyncRepository<T> where T : BaseEntity
|
||||
{
|
||||
private readonly CatalogContext _dbContext;
|
||||
protected readonly CatalogContext _dbContext;
|
||||
|
||||
public EfRepository(CatalogContext dbContext)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
}
|
||||
|
||||
public T GetById(int id)
|
||||
public virtual T GetById(int id)
|
||||
{
|
||||
return _dbContext.Set<T>().SingleOrDefault(e => e.Id == id);
|
||||
return _dbContext.Set<T>().Find(id);
|
||||
}
|
||||
|
||||
public List<T> List()
|
||||
public virtual async Task<T> GetByIdAsync(int id)
|
||||
{
|
||||
return _dbContext.Set<T>().ToList();
|
||||
return await _dbContext.Set<T>().FindAsync(id);
|
||||
}
|
||||
|
||||
public List<T> List(ISpecification<T> spec)
|
||||
public IEnumerable<T> ListAll()
|
||||
{
|
||||
return _dbContext.Set<T>().AsEnumerable();
|
||||
}
|
||||
|
||||
public async Task<List<T>> ListAllAsync()
|
||||
{
|
||||
return await _dbContext.Set<T>().ToListAsync();
|
||||
}
|
||||
|
||||
public IEnumerable<T> List(ISpecification<T> spec)
|
||||
{
|
||||
var queryableResultWithIncludes = spec.Includes
|
||||
.Aggregate(_dbContext.Set<T>().AsQueryable(),
|
||||
(current, include) => current.Include(include));
|
||||
return queryableResultWithIncludes
|
||||
.Aggregate(_dbContext.Set<T>().AsQueryable(),
|
||||
(current, include) => current.Include(include));
|
||||
var secondaryResult = spec.IncludeStrings
|
||||
.Aggregate(queryableResultWithIncludes,
|
||||
(current, include) => current.Include(include));
|
||||
return secondaryResult
|
||||
.Where(spec.Criteria)
|
||||
.ToList();
|
||||
.AsEnumerable();
|
||||
}
|
||||
public async Task<List<T>> ListAsync(ISpecification<T> spec)
|
||||
{
|
||||
var queryableResultWithIncludes = spec.Includes
|
||||
.Aggregate(_dbContext.Set<T>().AsQueryable(),
|
||||
(current, include) => current.Include(include));
|
||||
var secondaryResult = spec.IncludeStrings
|
||||
.Aggregate(queryableResultWithIncludes,
|
||||
(current, include) => current.Include(include));
|
||||
|
||||
return await secondaryResult
|
||||
.Where(spec.Criteria)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public T Add(T entity)
|
||||
@@ -43,10 +75,12 @@ namespace Infrastructure.Data
|
||||
return entity;
|
||||
}
|
||||
|
||||
public void Delete(T entity)
|
||||
public async Task<T> AddAsync(T entity)
|
||||
{
|
||||
_dbContext.Set<T>().Remove(entity);
|
||||
_dbContext.SaveChanges();
|
||||
_dbContext.Set<T>().Add(entity);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
public void Update(T entity)
|
||||
@@ -54,6 +88,21 @@ namespace Infrastructure.Data
|
||||
_dbContext.Entry(entity).State = EntityState.Modified;
|
||||
_dbContext.SaveChanges();
|
||||
}
|
||||
public async Task UpdateAsync(T entity)
|
||||
{
|
||||
_dbContext.Entry(entity).State = EntityState.Modified;
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public void Delete(T entity)
|
||||
{
|
||||
_dbContext.Set<T>().Remove(entity);
|
||||
_dbContext.SaveChanges();
|
||||
}
|
||||
public async Task DeleteAsync(T entity)
|
||||
{
|
||||
_dbContext.Set<T>().Remove(entity);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
31
src/Infrastructure/Data/OrderRepository.cs
Normal file
31
src/Infrastructure/Data/OrderRepository.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using ApplicationCore.Entities.OrderAggregate;
|
||||
using ApplicationCore.Interfaces;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Infrastructure.Data
|
||||
{
|
||||
public class OrderRepository : EfRepository<Order>, IOrderRepository
|
||||
{
|
||||
public OrderRepository(CatalogContext dbContext) : base(dbContext)
|
||||
{
|
||||
}
|
||||
|
||||
public Order GetByIdWithItems(int id)
|
||||
{
|
||||
return _dbContext.Orders
|
||||
.Include(o => o.OrderItems)
|
||||
.Include("OrderItems.ItemOrdered")
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
public Task<Order> GetByIdWithItemsAsync(int id)
|
||||
{
|
||||
return _dbContext.Orders
|
||||
.Include(o => o.OrderItems)
|
||||
.Include("OrderItems.ItemOrdered")
|
||||
.FirstOrDefaultAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user