[英]Problem with loading related data in ef core using Ardalis Specification: List of objects evaluates to null
通过使用官方指南,我能够收集到所有需要的信息。
BookSpecification.cs
using Ardalis.Specification;
using Core.Entities.BookAggregate;
namespace Core.Specifications
{
public class BookSpecification : Specification<Book>
{
public BookSpecification()
{
Query.Include(b => b.BookTags);
Query.Include(b => b.BookCategories);
Query.Include(b => b.Chapters);
}
}
}
IService.cs
using Ardalis.Specification;
namespace Core.Interfaces
{
public interface IService<T> where T : class, IAggregateRoot
{
Task<T> GetByIdAsync(int id);
Task<IEnumerable<T>> ListAsync();
// Adapt to use specifications
Task<IEnumerable<T>> ListAsyncWithSpec(Specification<T> spec);
Task DeleteByIdAsync(int id);
Task AddAsync(T t);
Task UpdateAsyc(T t);
}
}
GenericService.cs
using Ardalis.Specification;
using Core.Interfaces;
using Core.Specifications;
namespace Core.Services
{
public class GenericService<T> : IService<T> where T : class, IAggregateRoot
{
private readonly IRepository<T> _repository;
private readonly IAppLogger<GenericService<T>> _logger;
public GenericService(IRepository<T> repository, IAppLogger<GenericService<T>> logger)
{
_repository = repository;
_logger = logger;
}
public async Task<T> GetByIdAsync(int id)
{
return await _repository.GetByIdAsync(id);
}
// Adapt to use specifications
public async Task<IEnumerable<T>> ListAsync()
{
return await _repository.ListAsync();
}
public async Task<IEnumerable<T>> ListAsyncWithSpec(Specification<T> spec)
{
return await _repository.ListAsync(spec);
}
public async Task DeleteByIdAsync(int id)
{
var t = await _repository.GetByIdAsync(id);
if (t == null)
{
_logger.Error($"Element with id: {id} can not be found!");
throw new ArgumentException($"Element with id: {id} can not be found!");
}
await _repository.DeleteAsync(t);
}
public async Task AddAsync(T t)
{
await _repository.AddAsync(t);
}
public async Task UpdateAsyc(T t)
{
await _repository.UpdateAsync(t);
}
}
}
BaseController.cs
使 GET 可覆盖
using Core.Interfaces;
using Microsoft.AspNetCore.Mvc;
namespace API.Controllers
{
public class BaseController<T> : Controller where T : class, IAggregateRoot
{
private protected readonly IService<T> _service;
public BaseController(IService<T> service)
{
_service = service;
}
[HttpGet]
public virtual async Task<IEnumerable<T>> Get()
{
return await _service.ListAsync();
}
[HttpGet("{id}")]
public async Task<T> Get(int id)
{
return await _service.GetByIdAsync(id);
}
[HttpPost]
public async Task<IActionResult> Post([FromBody] T t)
{
await _service.AddAsync(t);
return Ok(t);
}
[HttpPut("{id}")]
public virtual async Task<IActionResult> Put(int id, [FromBody] T t)
{
throw new NotImplementedException();
}
[HttpDelete("{id}")]
public async Task<IActionResult> Delete(int id)
{
if (await _service.GetByIdAsync(id) == null)
return NotFound();
await _service.DeleteByIdAsync(id);
return Ok();
}
}
}
BookController.cs
using Core.Entities.BookAggregate;
using Core.Interfaces;
using Core.Specifications;
using Microsoft.AspNetCore.Mvc;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace API.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class BookController : BaseController<Book>
{
public BookController(IService<Book> service) : base(service)
{
}
[HttpGet]
public override async Task<IEnumerable<Book>> Get()
{
return await _service.ListAsyncWithSpec(new BookSpecification());
}
[HttpPut("{id}")]
public override async Task<IActionResult> Put(int id, [FromBody] Book book)
{
Book entity = await _service.GetByIdAsync(id);
entity.Title = book.Title;
entity.Chapters = book.Chapters;
await _service.UpdateAsyc(entity);
return Ok(entity);
}
}
}
Program.cs
忽略圆圈
builder.Services.AddControllers().AddJsonOptions(x => x.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.