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:
Steve Smith
2017-09-22 11:28:55 -04:00
committed by GitHub
parent b90bd08d11
commit aca618316a
70 changed files with 1755 additions and 513 deletions

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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();
}
}
}

View 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();
}
}
}