我正在编写一个Entity Framework Command,用于从数据库中仅选择一个记录(书)。它需要通过api显示,其中用户应通过url提供ID。另外,由于表与其他表(作家,类型)有关,因此需要包括这些表中的相关记录。图书可以具有更多类型,并将其存储在BookGenres表中,然后该表与Genre表相关。此外,Book在表中有一个Writer具有相同的名称。 BookDto是仅返回最终用户相关数据的对象。命令如下:
EfGetBookCommand:IGetBookCommand
private readonly LibraryContext _context;
public EfGetBookCommand(LibraryContext context)
{
_context = context;
}
public BookDto Execute(int request)
{
//var book = _context.Books.AsQueryable();
var book = _context.Books.AsQueryable();
if (book == null)
{
throw new Exception();
}
var result = book
.Include(b => b.Writer)
.ThenInclude(w => w.Name)
.Include(b => b.BookGenres)
.ThenInclude(bg => bg.Genre)
.Where(b => b.Id == request)
.First();
return new BookDto
{
Id = result.Id,
Title = result.Title,
Writer = result.Writer.Name,
Description = result.Description,
AvailableCount = result.AvailableCount,
Count = result.Count,
BookGenres = result.BookGenres.Select(bg => bg.Genre.Name)
};
当我通过诸如http://localhost:55666/api/books/4这样的GET请求在邮递员中尝试此操作时,我得到404。由于无法将其与Include结合使用,因此无法使用find。我将展示相关课程。
我已经有类似的命令可以退回所有书籍,并且它可以正常工作,所以我无法找到问题所在。
BooksController(在API应用程序中)
public class BooksController : ControllerBase
{
private IGetBooksCommand _command;
private IGetBookCommand _command2;
public BooksController(IGetBooksCommand command, IGetBookCommand command2)
{
_command = command;
_command2 = command2;
}
[HttpGet("{id}")]
public IActionResult Get(int id)
{
try
{
var BookDto = _command2.Execute(id);
return Ok(BookDto);
}
catch(Exception e)
{
return NotFound();
}
}
BookDto
public class BookDto
{
public int Id { get; set; }
public string Title { get; set; }
public string Writer { get; set; }
public string Description { get; set; }
public int AvailableCount { get; set; }
public int Count { get; set; }
public IEnumerable<string> BookGenres { get; set; }
}
书(实体框架代码的域类优先方法)
public class Book : BaseEntity
{
public string Title { get; set; }
public int WriterId { get; set; }
public Writer Writer { get; set; }
public string Description { get; set; }
public int AvailableCount { get; set; }
public int Count { get; set; } reserved or not
public ICollection<BookGenre> BookGenres { get; set; }
public ICollection<BookReservation> BookReservations { get; set; }
}
BookGenre(DomainClass)
public class BookGenre
{
public int BookId { get; set; }
public int GenreId { get; set; }
public Book Book { get; set; }
public Genre Genre { get; set; }
}
类型(DomainClass)
public class Genre : BaseEntity
{
public string Name { get; set; }
public ICollection<BookGenre> BookGenres { get; set; }
}
Writer(DomainClass)
ICommand
public interface ICommand<TRequest>
{
void Execute(TRequest request);
}
public interface ICommand<TRequest, TResult>
{
TResult Execute(TRequest request);
}
IGetBookCommand
public interface IGetBookCommand : ICommand<int, BookDto>
{
}
我应该在json中返回一个BookDto对象,但出现404错误。
答案 0 :(得分:0)
我怀疑var BookDto = _command2.Execute(id);
行中有内容
当我检查您的代码库时,我可以看到一个具有相同名称的类已经存在,并且您尝试再次重新创建它。
自从您返回return NotFound();
以来,请尝试确保正确完成路由,并且操作已触发。
我建议使用AttributeRouting
之类的
[Route("~/api/books/{id}")] [HttpGet]
public IActionResult Get(int id)
{
try
{
var result= _command2.Execute(id);
return Ok(result);
}
catch(Exception e)
{
// Try returning some other exception other than 404.
}
}
答案 1 :(得分:0)
尝试遵循以下方法。您的初始查询正在调用AsQueryable(),这将导致sql执行,并且您会松散延迟加载。您可以将所有sql逻辑组合到主查询中,并立即获取所有联接表。由于我没有所有代码,这可能会有一些语法错误。
public BookDto Execute(int request)
{
var book = _context.Books
.Single(b => b.Id == request)
.Select(s => new BookDto() {
Id = s.Id,
Title = s.Title,
Writer = s.Writer.Name,
Description = s.Description,
AvailableCount = s.AvailableCount,
BookGenres = s.BookGenres.ToList()
});
}