зеркало из 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()
|
private async Task<List<Genre>> GetGenres()
|
||||||
{
|
{
|
||||||
// TODO [EF] We don't query related data as yet, so the OrderByDescending isn't doing anything
|
return await DbContext.Genres
|
||||||
//var genres = _dbContext.Genres
|
.Include(g => g.Albums).ThenInclude(a => a.OrderDetails)
|
||||||
//.OrderByDescending(
|
// TODO use nested sum https://github.com/aspnet/EntityFramework/issues/3792
|
||||||
// g => g.Albums.Sum(
|
//.OrderByDescending(
|
||||||
// a => a.OrderDetails.Sum(
|
// g => g.Albums.Sum(a => a.OrderDetails.Sum(od => od.Quantity)))
|
||||||
// od => od.Quantity)))
|
.Take(9)
|
||||||
//.Take(9)
|
.ToListAsync();
|
||||||
//.ToList();
|
|
||||||
|
|
||||||
return await DbContext.Genres.Take(9).ToListAsync();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -60,9 +60,8 @@ namespace MusicStore.Controllers
|
||||||
// Group the order details by album and return
|
// Group the order details by album and return
|
||||||
// the albums with the highest count
|
// 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
|
return await dbContext.Albums
|
||||||
.OrderByDescending(a => a.OrderDetails.Count())
|
.OrderByDescending(a => a.OrderDetails.Count)
|
||||||
.Take(count)
|
.Take(count)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace MusicStore.Models
|
||||||
{
|
{
|
||||||
public class CartItem
|
public class CartItem
|
||||||
{
|
{
|
||||||
|
[Key]
|
||||||
public int CartItemId { get; set; }
|
public int CartItemId { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
|
|
|
@ -13,20 +13,5 @@ namespace MusicStore.Models
|
||||||
public DbSet<Genre> Genres { get; set; }
|
public DbSet<Genre> Genres { get; set; }
|
||||||
public DbSet<CartItem> CartItems { get; set; }
|
public DbSet<CartItem> CartItems { get; set; }
|
||||||
public DbSet<OrderDetail> OrderDetails { 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 = "אריק אינשטיין"}
|
new Artist { Name = "אריק אינשטיין"}
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO [EF] Swap to store generated keys when available
|
|
||||||
int artistId = 1;
|
|
||||||
artists = new Dictionary<string, Artist>();
|
artists = new Dictionary<string, Artist>();
|
||||||
foreach (Artist artist in artistsList)
|
foreach (Artist artist in artistsList)
|
||||||
{
|
{
|
||||||
artist.ArtistId = artistId++;
|
|
||||||
artists.Add(artist.Name, artist);
|
artists.Add(artist.Name, artist);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -954,15 +951,9 @@ namespace MusicStore.Models
|
||||||
};
|
};
|
||||||
|
|
||||||
genres = new Dictionary<string, Genre>();
|
genres = new Dictionary<string, Genre>();
|
||||||
// TODO [EF] Swap to store generated keys when available
|
|
||||||
int genreId = 1;
|
|
||||||
foreach (Genre genre in genresList)
|
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);
|
genres.Add(genre.Name, genre);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,25 +10,25 @@ namespace MusicStore.Models
|
||||||
public class ShoppingCart
|
public class ShoppingCart
|
||||||
{
|
{
|
||||||
private readonly MusicStoreContext _dbContext;
|
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;
|
_dbContext = dbContext;
|
||||||
|
_shoppingCartId = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ShoppingCart GetCart(MusicStoreContext db, HttpContext context)
|
public static ShoppingCart GetCart(MusicStoreContext db, HttpContext context)
|
||||||
{
|
=> GetCart(db, GetCartId(context));
|
||||||
var cart = new ShoppingCart(db);
|
|
||||||
cart.ShoppingCartId = cart.GetCartId(context);
|
public static ShoppingCart GetCart(MusicStoreContext db, string cartId)
|
||||||
return cart;
|
=> new ShoppingCart(db, cartId);
|
||||||
}
|
|
||||||
|
|
||||||
public void AddToCart(Album album)
|
public void AddToCart(Album album)
|
||||||
{
|
{
|
||||||
// Get the matching cart and album instances
|
// Get the matching cart and album instances
|
||||||
var cartItem = _dbContext.CartItems.SingleOrDefault(
|
var cartItem = _dbContext.CartItems.SingleOrDefault(
|
||||||
c => c.CartId == ShoppingCartId
|
c => c.CartId == _shoppingCartId
|
||||||
&& c.AlbumId == album.AlbumId);
|
&& c.AlbumId == album.AlbumId);
|
||||||
|
|
||||||
if (cartItem == null)
|
if (cartItem == null)
|
||||||
|
@ -37,7 +37,7 @@ namespace MusicStore.Models
|
||||||
cartItem = new CartItem
|
cartItem = new CartItem
|
||||||
{
|
{
|
||||||
AlbumId = album.AlbumId,
|
AlbumId = album.AlbumId,
|
||||||
CartId = ShoppingCartId,
|
CartId = _shoppingCartId,
|
||||||
Count = 1,
|
Count = 1,
|
||||||
DateCreated = DateTime.Now
|
DateCreated = DateTime.Now
|
||||||
};
|
};
|
||||||
|
@ -55,7 +55,7 @@ namespace MusicStore.Models
|
||||||
{
|
{
|
||||||
// Get the cart
|
// Get the cart
|
||||||
var cartItem = _dbContext.CartItems.Single(
|
var cartItem = _dbContext.CartItems.Single(
|
||||||
cart => cart.CartId == ShoppingCartId
|
cart => cart.CartId == _shoppingCartId
|
||||||
&& cart.CartItemId == id);
|
&& cart.CartItemId == id);
|
||||||
|
|
||||||
int itemCount = 0;
|
int itemCount = 0;
|
||||||
|
@ -76,39 +76,45 @@ namespace MusicStore.Models
|
||||||
return itemCount;
|
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);
|
_dbContext.CartItems.RemoveRange(cartItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<CartItem>> GetCartItems()
|
public Task<List<CartItem>> GetCartItems()
|
||||||
{
|
{
|
||||||
return await _dbContext.CartItems.
|
return _dbContext.CartItems.
|
||||||
Where(cart => cart.CartId == ShoppingCartId).
|
Where(cart => cart.CartId == _shoppingCartId).
|
||||||
Include(c => c.Album).
|
Include(c => c.Album).
|
||||||
ToListAsync();
|
ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> GetCount()
|
public Task<int> GetCount()
|
||||||
{
|
{
|
||||||
// Get the count of each item in the cart and sum them up
|
// Get the count of each item in the cart and sum them up
|
||||||
return await (from cartItem in _dbContext.CartItems
|
return _dbContext
|
||||||
where cartItem.CartId == ShoppingCartId
|
.CartItems
|
||||||
select cartItem.Count).SumAsync();
|
.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
|
// Multiply album price by count of that album to get
|
||||||
// the current price for each of those albums in the cart
|
// the current price for each of those albums in the cart
|
||||||
// sum all album price totals to get the cart total
|
// 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 _dbContext.CartItems
|
||||||
return await (from cartItem in _dbContext.CartItems
|
.Include(c => c.Album)
|
||||||
join album in _dbContext.Albums on cartItem.AlbumId equals album.AlbumId
|
.Where(c => c.CartId == _shoppingCartId)
|
||||||
where cartItem.CartId == ShoppingCartId
|
.Select(c => c.Album.Price * c.Count)
|
||||||
select cartItem.Count * album.Price).SumAsync();
|
.SumAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> CreateOrder(Order order)
|
public async Task<int> CreateOrder(Order order)
|
||||||
|
@ -148,7 +154,7 @@ namespace MusicStore.Models
|
||||||
}
|
}
|
||||||
|
|
||||||
// We're using HttpContextBase to allow access to sessions.
|
// 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");
|
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>();
|
||||||
|
}
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче