Я написал API с использованием Entity Framework и пытаюсь оптимизировать его обращения к базе данных.
Когда я получаю объект (мы назовем его Page
), у которого есть много связанных объектов, я использую .Include()
метод linq, который предотвращает вызовы N + 1.
Мой основной объект (назовем его Book
) имеет много Page
. Когда я получаю Book
из db, я делаю это 2 раза на моей фабрике DAL, чтобы предотвратить массивный одиночный запрос (у моего Page
есть 10 связанных объектов, а у моего Book
есть 4):
public async Task<IBook>GetById(int myBookId) {
var Pages = myDbContext.Page
.Where(x => x.BookId == myBookId && x.IsChapter)
.Include(x => x.prop1)
.Include(x => x.prop2) etc
var myBook = await myDbContext.Book
.Where(x => x.Id == myBookId)
.Include(x => x.bprop1)
.FirstOrDefaultAsync()
myBook.Pages = Pages.ToList();
}
Это работает, и мой сгенерированный SQL - именно то, что я хочу:
select *
from Page
where page_Chapter = 1 and page_bookId = @EntityKeyValue1
и
select *
from Book
where book_Id = @EntityKeyValue1
с *
, фактически являющимся столбцами связанных таблиц.
Теперь моя проблема в том, что, когда я пытаюсь преобразовать мой объект из объекта базы данных в передний объект, делается новый запрос для Page
, который равен
select *
from page
where page_bookId = @EntityKeyValue1.
Вот как я делаю преобразование:
public async Task<BookModel> GetBookById(int id)
{
using (var context = _dalFactory.GetNewContext(EPurpose.SELECT))
{
var t = (await _dalFactory.GetBookRepository(context).GetById(id)).ConvertToModel();
return t;
}
}
и мой Convert()
метод:
public static BookModel Convert(this Book book)
{
if (book == null)
return null;
BookModel toReturn = new BookModel
{
toReturn.Id = book.Id,
toReturn.intP = book.intP,
...
};
if (book.Page != null)
{
var PageModelList = new List<PageModel>();
//then I convert my book.Page to PageModel list and assign toReturn.Page to that.
}
}
Запрос сделан, как только я проверю book.Page != null
.
Есть мысли о том, как предотвратить двойной запрос? На самом деле мне просто нужно около 10% Page
, полученных в последнем запросе