Используя EF Core 2.2.2, в моей базе данных есть таблица, которая используется для хранения заметок для многих других таблиц.Другими словами, это своего рода таблица подробностей в отношениях мастер-детализация, но с несколькими мастер-таблицами.Рассмотрим упрощенную модель EF:
public class Person
{
public Guid PersonID { get; set; }
public string Name { set; set; }
}
public class InvoiceItem
{
public Guid InvoiceItemID { get; set; }
public Guid InvoiceID { get; set; }
public string Description { get; set; }
}
public class Invoice
{
public Guid InvoiceID { get; set; }
public int InvoiceNumber { get; set; }
public List<Item> Items { get; set; }
}
public class Notes
{
public Guid NoteID { get; set; }
public Guid NoteParentID { get; set; }
public DateTime NoteDate { get; set; }
public string Note { get; set; }
}
В этом случае Notes может хранить заметки Person или заметки Invoice (или заметки InvoiceItem, хотя давайте просто скажем, что пользовательский интерфейс этого не поддерживает).
У меня есть методы запросов, настроенные следующим образом:
public IQueryable<PersonDTO> GetPersonQuery()
{
return from p in Context.People
select new PersonDTO
{
PersonID = p.PersonID,
Name = p.Name
};
}
public List<PersonDTO> GetPeople()
{
return (from p in GetPersonQuery()
return p).ToList();
}
public IQueryable<InvoiceDTO> GetInvoiceQuery()
{
return from p in Context.Invoices
select new InvoiceDTO
{
InvoiceID = p.InvoiceID,
InvoiceNumber = p.InvoiceNumber
};
}
public List<InvoiceDTO> GetInvoices()
{
return (from i in GetInvoiceQuery()
return i).ToList();
}
Все они работают как положено.Теперь, допустим, я добавляю InvoiceItems к запросу Invoice, например:
public IQueryable<InvoiceDTO> GetInvoiceQuery()
{
return from p in Context.Invoices
select new InvoiceDTO
{
InvoiceID = p.InvoiceID,
InvoiceNumber = p.InvoiceNumber,
Items = (from ii in p.Items
select new ItemDTO
{
ItemID = ii.ItemID,
Description = ii.Description
}).ToList()
};
}
Это также прекрасно работает и выдает всего пару запросов.Однако следующее:
public IQueryable<InvoiceDTO> GetInvoiceQuery()
{
return from p in Context.Invoices
select new InvoiceDTO
{
InvoiceID = p.InvoiceID,
InvoiceNumber = p.InvoiceNumber,
Items = (from ii in p.Items
select new ItemDTO
{
ItemID = ii.ItemID,
Description = ii.Description
}).ToList(),
Notes = (from n in Context.Notes
where i.InvoiceID = n.NoteParentID
select new NoteDTO
{
NoteID = n.NoteID,
Note = n.Note
}).ToList(),
};
}
отправляет отдельный запрос к таблице примечаний для каждой строки счета в таблице счетов.Таким образом, если в таблице «Счета-фактуры» имеется 1000 счетов-фактур, в базу данных отправляется примерно 1 1001 запрос.
Похоже, что подзапрос «Предметы» не имеет той же проблемы, поскольку существует явная связь между «Счета-фактуры» и «Предметы», в то время как между Счетами-фактурами и «Примечаниями» нет конкретной связи (поскольку не все примечания связаны со счетами-фактурами).).
Есть ли способ переписать этот окончательный запрос, чтобы он не отправлял отдельный запрос на примечание для каждого счета в таблице?