Merge branch 'master' into pr/119
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.eShopWeb.ApplicationCore.Entities;
|
||||
using Microsoft.eShopWeb.ApplicationCore.Entities;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -31,7 +31,6 @@ namespace Microsoft.eShopWeb.Infrastructure.Data
|
||||
return List(spec).FirstOrDefault();
|
||||
}
|
||||
|
||||
|
||||
public virtual async Task<T> GetByIdAsync(int id)
|
||||
{
|
||||
return await _dbContext.Set<T>().FindAsync(id);
|
||||
@@ -42,44 +41,28 @@ namespace Microsoft.eShopWeb.Infrastructure.Data
|
||||
return _dbContext.Set<T>().AsEnumerable();
|
||||
}
|
||||
|
||||
public async Task<List<T>> ListAllAsync()
|
||||
public async Task<IReadOnlyList<T>> ListAllAsync()
|
||||
{
|
||||
return await _dbContext.Set<T>().ToListAsync();
|
||||
}
|
||||
|
||||
public IEnumerable<T> List(ISpecification<T> spec)
|
||||
{
|
||||
// fetch a Queryable that includes all expression-based includes
|
||||
var queryableResultWithIncludes = spec.Includes
|
||||
.Aggregate(_dbContext.Set<T>().AsQueryable(),
|
||||
(current, include) => current.Include(include));
|
||||
|
||||
// modify the IQueryable to include any string-based include statements
|
||||
var secondaryResult = spec.IncludeStrings
|
||||
.Aggregate(queryableResultWithIncludes,
|
||||
(current, include) => current.Include(include));
|
||||
|
||||
// return the result of the query using the specification's criteria expression
|
||||
return secondaryResult
|
||||
.Where(spec.Criteria)
|
||||
.AsEnumerable();
|
||||
return ApplySpecification(spec).AsEnumerable();
|
||||
}
|
||||
public async Task<List<T>> ListAsync(ISpecification<T> spec)
|
||||
public async Task<IReadOnlyList<T>> ListAsync(ISpecification<T> spec)
|
||||
{
|
||||
// fetch a Queryable that includes all expression-based includes
|
||||
var queryableResultWithIncludes = spec.Includes
|
||||
.Aggregate(_dbContext.Set<T>().AsQueryable(),
|
||||
(current, include) => current.Include(include));
|
||||
|
||||
// modify the IQueryable to include any string-based include statements
|
||||
var secondaryResult = spec.IncludeStrings
|
||||
.Aggregate(queryableResultWithIncludes,
|
||||
(current, include) => current.Include(include));
|
||||
|
||||
// return the result of the query using the specification's criteria expression
|
||||
return await secondaryResult
|
||||
.Where(spec.Criteria)
|
||||
.ToListAsync();
|
||||
return await ApplySpecification(spec).ToListAsync();
|
||||
}
|
||||
|
||||
public int Count(ISpecification<T> spec)
|
||||
{
|
||||
return ApplySpecification(spec).Count();
|
||||
}
|
||||
|
||||
public async Task<int> CountAsync(ISpecification<T> spec)
|
||||
{
|
||||
return await ApplySpecification(spec).CountAsync();
|
||||
}
|
||||
|
||||
public T Add(T entity)
|
||||
@@ -103,6 +86,7 @@ namespace Microsoft.eShopWeb.Infrastructure.Data
|
||||
_dbContext.Entry(entity).State = EntityState.Modified;
|
||||
_dbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public async Task UpdateAsync(T entity)
|
||||
{
|
||||
_dbContext.Entry(entity).State = EntityState.Modified;
|
||||
@@ -114,10 +98,16 @@ namespace Microsoft.eShopWeb.Infrastructure.Data
|
||||
_dbContext.Set<T>().Remove(entity);
|
||||
_dbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public async Task DeleteAsync(T entity)
|
||||
{
|
||||
_dbContext.Set<T>().Remove(entity);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
private IQueryable<T> ApplySpecification(ISpecification<T> spec)
|
||||
{
|
||||
return SpecificationEvaluator<T>.GetQuery(_dbContext.Set<T>().AsQueryable(), spec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.eShopWeb.Infrastructure.Data.Migrations
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate;
|
||||
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopWeb.Infrastructure.Data
|
||||
@@ -12,20 +11,12 @@ namespace Microsoft.eShopWeb.Infrastructure.Data
|
||||
{
|
||||
}
|
||||
|
||||
public Order GetByIdWithItems(int id)
|
||||
{
|
||||
return _dbContext.Orders
|
||||
.Include(o => o.OrderItems)
|
||||
.Include($"{nameof(Order.OrderItems)}.{nameof(OrderItem.ItemOrdered)}")
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
public Task<Order> GetByIdWithItemsAsync(int id)
|
||||
{
|
||||
return _dbContext.Orders
|
||||
.Include(o => o.OrderItems)
|
||||
.Include($"{nameof(Order.OrderItems)}.{nameof(OrderItem.ItemOrdered)}")
|
||||
.FirstOrDefaultAsync();
|
||||
.FirstOrDefaultAsync(x => x.Id == id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
50
src/Infrastructure/Data/SpecificationEvaluator.cs
Normal file
50
src/Infrastructure/Data/SpecificationEvaluator.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.eShopWeb.ApplicationCore.Entities;
|
||||
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.eShopWeb.Infrastructure.Data
|
||||
{
|
||||
public class SpecificationEvaluator<T> where T : BaseEntity
|
||||
{
|
||||
public static IQueryable<T> GetQuery(IQueryable<T> inputQuery, ISpecification<T> specification)
|
||||
{
|
||||
var query = inputQuery;
|
||||
|
||||
// modify the IQueryable using the specification's criteria expression
|
||||
if (specification.Criteria != null)
|
||||
{
|
||||
query = query.Where(specification.Criteria);
|
||||
}
|
||||
|
||||
// Includes all expression-based includes
|
||||
query = specification.Includes.Aggregate(query,
|
||||
(current, include) => current.Include(include));
|
||||
|
||||
// Include any string-based include statements
|
||||
query = specification.IncludeStrings.Aggregate(query,
|
||||
(current, include) => current.Include(include));
|
||||
|
||||
// Apply ordering if expressions are set
|
||||
if (specification.OrderBy != null)
|
||||
{
|
||||
query = query.OrderBy(specification.OrderBy);
|
||||
}
|
||||
else if (specification.OrderByDescending != null)
|
||||
{
|
||||
query = query.OrderByDescending(specification.OrderByDescending);
|
||||
}
|
||||
|
||||
// Apply paging if enabled
|
||||
if (specification.isPagingEnabled)
|
||||
{
|
||||
query = query.Skip(specification.Skip)
|
||||
.Take(specification.Take);
|
||||
}
|
||||
return query;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user