如何仅从数据库中选择一条记录,但也包括相关表中的数据



我正在编写一个实体框架命令,用于仅从数据库中选择一条记录(书籍)。它需要通过 api 显示,用户应通过 url 提供 id。此外,由于表与其他表(作家、流派)相关,因此需要包含这些表中的相关记录。书籍可以具有更多流派,并将其存储在"书籍流派"表中,然后与"流派"表相关。此外,Book 还有一个同名的表中的编写器。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)
};

当我通过 GET 请求在邮递员中尝试这样做时,如下所示:http://localhost:55666/api/books/4,我得到 404。我无法使用查找,因为我无法将其与包含结合使用。我将展示相关类。

我已经有类似的命令来返回所有书籍,它可以工作,所以我无法找到它有什么问题。

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; }
}

书籍类型(域类)

public class BookGenre
{
public int BookId { get; set; }
public int GenreId { get; set; }
public Book Book { get; set; }
public Genre Genre { get; set; }
}

流派(域类)

public class Genre : BaseEntity
{
public string Name { get; set; }
public ICollection<BookGenre> BookGenres { get; set; }
}

作家(域类)

伊科曼德

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 错误。

我怀疑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.
}
}

尝试这些方法。您的初始查询正在调用 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()
});
}

相关内容

最新更新