This commit is contained in:
Nate McMaster 2016-03-03 11:46:37 -08:00
Родитель fc1a1c8a49
Коммит 0ae07188fc
7 изменённых файлов: 98 добавлений и 64 удалений

Просмотреть файл

@ -26,16 +26,13 @@ namespace MusicStore.Components
private async Task<List<Genre>> GetGenres()
{
// TODO [EF] We don't query related data as yet, so the OrderByDescending isn't doing anything
//var genres = _dbContext.Genres
//.OrderByDescending(
// g => g.Albums.Sum(
// a => a.OrderDetails.Sum(
// od => od.Quantity)))
//.Take(9)
//.ToList();
return await DbContext.Genres.Take(9).ToListAsync();
return await DbContext.Genres
.Include(g => g.Albums).ThenInclude(a => a.OrderDetails)
// TODO use nested sum https://github.com/aspnet/EntityFramework/issues/3792
//.OrderByDescending(
// g => g.Albums.Sum(a => a.OrderDetails.Sum(od => od.Quantity)))
.Take(9)
.ToListAsync();
}
}
}

Просмотреть файл

@ -60,9 +60,8 @@ namespace MusicStore.Controllers
// Group the order details by album and return
// the albums with the highest count
// TODO [EF] We don't query related data as yet, so the OrderByDescending isn't doing anything
return await dbContext.Albums
.OrderByDescending(a => a.OrderDetails.Count())
.OrderByDescending(a => a.OrderDetails.Count)
.Take(count)
.ToListAsync();
}

Просмотреть файл

@ -5,6 +5,7 @@ namespace MusicStore.Models
{
public class CartItem
{
[Key]
public int CartItemId { get; set; }
[Required]

Просмотреть файл

@ -13,20 +13,5 @@ namespace MusicStore.Models
public DbSet<Genre> Genres { get; set; }
public DbSet<CartItem> CartItems { get; set; }
public DbSet<OrderDetail> OrderDetails { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<CartItem>().HasKey(b => b.CartItemId);
// TODO: Remove when explicit values insertion removed.
builder.Entity<Artist>().Property(a => a.ArtistId).ValueGeneratedNever();
builder.Entity<Genre>().Property(g => g.GenreId).ValueGeneratedNever();
//Deleting an album fails with this relation
builder.Entity<Album>().Ignore(a => a.OrderDetails);
builder.Entity<OrderDetail>().Ignore(od => od.Album);
base.OnModelCreating(builder);
}
}
}

Просмотреть файл

@ -913,12 +913,9 @@ namespace MusicStore.Models
new Artist { Name = "אריק אינשטיין"}
};
// TODO [EF] Swap to store generated keys when available
int artistId = 1;
artists = new Dictionary<string, Artist>();
foreach (Artist artist in artistsList)
{
artist.ArtistId = artistId++;
artists.Add(artist.Name, artist);
}
}
@ -954,15 +951,9 @@ namespace MusicStore.Models
};
genres = new Dictionary<string, Genre>();
// TODO [EF] Swap to store generated keys when available
int genreId = 1;
foreach (Genre genre in genresList)
{
genre.GenreId = genreId++;
// TODO [EF] Remove when null values are supported by update pipeline
genre.Description = genre.Name + " is great music (if you like it).";
genres.Add(genre.Name, genre);
}
}

Просмотреть файл

@ -10,25 +10,25 @@ namespace MusicStore.Models
public class ShoppingCart
{
private readonly MusicStoreContext _dbContext;
private string ShoppingCartId { get; set; }
private readonly string _shoppingCartId;
public ShoppingCart(MusicStoreContext dbContext)
private ShoppingCart(MusicStoreContext dbContext, string id)
{
_dbContext = dbContext;
_shoppingCartId = id;
}
public static ShoppingCart GetCart(MusicStoreContext db, HttpContext context)
{
var cart = new ShoppingCart(db);
cart.ShoppingCartId = cart.GetCartId(context);
return cart;
}
public static ShoppingCart GetCart(MusicStoreContext db, HttpContext context)
=> GetCart(db, GetCartId(context));
public static ShoppingCart GetCart(MusicStoreContext db, string cartId)
=> new ShoppingCart(db, cartId);
public void AddToCart(Album album)
{
// Get the matching cart and album instances
var cartItem = _dbContext.CartItems.SingleOrDefault(
c => c.CartId == ShoppingCartId
c => c.CartId == _shoppingCartId
&& c.AlbumId == album.AlbumId);
if (cartItem == null)
@ -37,7 +37,7 @@ namespace MusicStore.Models
cartItem = new CartItem
{
AlbumId = album.AlbumId,
CartId = ShoppingCartId,
CartId = _shoppingCartId,
Count = 1,
DateCreated = DateTime.Now
};
@ -55,7 +55,7 @@ namespace MusicStore.Models
{
// Get the cart
var cartItem = _dbContext.CartItems.Single(
cart => cart.CartId == ShoppingCartId
cart => cart.CartId == _shoppingCartId
&& cart.CartItemId == id);
int itemCount = 0;
@ -76,39 +76,45 @@ namespace MusicStore.Models
return itemCount;
}
public void EmptyCart()
public async void EmptyCart()
{
var cartItems = _dbContext.CartItems.Where(cart => cart.CartId == ShoppingCartId).ToArray();
var cartItems = await _dbContext
.CartItems
.Where(cart => cart.CartId == _shoppingCartId)
.ToArrayAsync();
_dbContext.CartItems.RemoveRange(cartItems);
}
public async Task<List<CartItem>> GetCartItems()
public Task<List<CartItem>> GetCartItems()
{
return await _dbContext.CartItems.
Where(cart => cart.CartId == ShoppingCartId).
return _dbContext.CartItems.
Where(cart => cart.CartId == _shoppingCartId).
Include(c => c.Album).
ToListAsync();
}
public async Task<int> GetCount()
public Task<int> GetCount()
{
// Get the count of each item in the cart and sum them up
return await (from cartItem in _dbContext.CartItems
where cartItem.CartId == ShoppingCartId
select cartItem.Count).SumAsync();
return _dbContext
.CartItems
.Where(c => c.CartId == _shoppingCartId)
.Select(c => c.Count)
.SumAsync();
}
public async Task<decimal> GetTotal()
public Task<decimal> GetTotal()
{
// Multiply album price by count of that album to get
// the current price for each of those albums in the cart
// sum all album price totals to get the cart total
// TODO: Use nav prop traversal instead of joins (EF #https://github.com/aspnet/EntityFramework/issues/325)
return await (from cartItem in _dbContext.CartItems
join album in _dbContext.Albums on cartItem.AlbumId equals album.AlbumId
where cartItem.CartId == ShoppingCartId
select cartItem.Count * album.Price).SumAsync();
return _dbContext.CartItems
.Include(c => c.Album)
.Where(c => c.CartId == _shoppingCartId)
.Select(c => c.Album.Price * c.Count)
.SumAsync();
}
public async Task<int> CreateOrder(Order order)
@ -148,7 +154,7 @@ namespace MusicStore.Models
}
// We're using HttpContextBase to allow access to sessions.
private string GetCartId(HttpContext context)
private static string GetCartId(HttpContext context)
{
var cartId = context.Session.GetString("Session");

Просмотреть файл

@ -0,0 +1,55 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using MusicStore.Models;
using Xunit;
namespace MusicStore.Test
{
public class ShoppingCartTest : IClassFixture<ShoppingCartFixture>
{
private readonly ShoppingCartFixture _fixture;
public ShoppingCartTest(ShoppingCartFixture fixture)
{
_fixture = fixture;
}
[Fact]
public async void ComputesTotal()
{
var cartId = Guid.NewGuid().ToString();
using (var db = _fixture.CreateContext())
{
var a = db.Albums.Add(
new Album
{
Price = 15.99m
}).Entity;
db.CartItems.Add(new CartItem { Album = a, Count = 2, CartId = cartId });
db.SaveChanges();
Assert.Equal(31.98m, await ShoppingCart.GetCart(db, cartId).GetTotal());
}
}
}
public class ShoppingCartFixture
{
private readonly IServiceProvider _serviceProvider;
public ShoppingCartFixture()
{
var services = new ServiceCollection();
services.AddEntityFramework()
.AddInMemoryDatabase()
.AddDbContext<MusicStoreContext>(options => options.UseInMemoryDatabase());
_serviceProvider = services.BuildServiceProvider();
}
public virtual MusicStoreContext CreateContext()
=> _serviceProvider.GetRequiredService<MusicStoreContext>();
}
}