зеркало из https://github.com/aspnet/MusicStore.git
Cleanup some EF TODOs
This commit is contained in:
Родитель
fc1a1c8a49
Коммит
0ae07188fc
|
@ -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>();
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче