Это кажется мне произвольным, когда мне приходится иметь дело с .Include()
связанными сущностями, а когда нет. В некоторых случаях EF дает мне информацию о связанных объектах без нее, а в других случаях он ничего не может сделать со связанными объектами, потому что я их не включил:
Работает без .Include ();
Это пример, когда я загружаю данные без .Include ();
public class InvoiceService
{
private ApplicationDbContext db { get; set; }
public InvoiceService(ApplicationDbContext context)
{
db = context;
}
public Invoice Get(int id)
{
return db.Invoices.SingleOrDefault(x => x.Id == id);
}
}
public partial class ShowInvoice : System.Web.UI.Page
{
private InvoiceService invoiceService;
private readonly ApplicationDbContext context = new ApplicationDbContext();
protected void Page_Load(object sender, EventArgs e)
{
invoiceService = new InvoiceService(context);
if (!IsPostBack)
{
int.TryParse(Request.QueryString["invoiceId"].ToString(), out int invoiceId);
LoadInvoice(invoiceId);
}
}
private void LoadInvoice(int invoiceId)
{
var invoice = invoiceService.Get(invoiceId);
// Other code irrelevant to the question goes here.
}
}
Ниже приведен результат, включающий данные для компании, связанные с запрашиваемым счетом:
![enter image description here](https://i.stack.imgur.com/KsMDi.png)
Как видите, информация для компании определенно поступает, но не была явно включена.
Не работает без .Include ();
И наоборот, я сделал некоторое сопоставление со счетами в этом же проекте, и я получил NullReferenceExceptions при извлечении значений свойств связанных сущностей, потому что я не .Include()
.
Этот метод получает все утвержденные записи расписания для указанной компании. Эта модель представления предназначена исключительно для управления связью записей расписания для счета-фактуры (поэтому вы выставляете счета на основании выбранных записей расписания).
public List<InvoiceTimesheetViewModel> GetInvoiceTimesheetsByCompanyId(int companyId)
{
var factory = new TimesheetViewModelsFactory();
var timesheets = db.Timesheets.Where(x => x.Approved && x.Company.Id == companyId && !x.Deleted).ToList();
return factory.GetInvoiceTimesheetsViewModel(timesheets);
}
Исключения NullReferenceException возникли на фабрике, которая отображает сущности расписания в модель представления:
public List<InvoiceTimesheetViewModel> GetInvoiceTimesheetsViewModel(List<Timesheet> timesheets)
{
var model = new List<InvoiceTimesheetViewModel>();
foreach (var timesheet in timesheets)
{
var start = DateTime.Parse((timesheet.DateAdded + timesheet.StartTime).ToString());
var finished = DateTime.Parse((timesheet.DateCompleted + timesheet.EndTime).ToString());
DateTime.TryParse(timesheet.RelevantDate.ToString(), out DateTime relevant);
model.Add(new InvoiceTimesheetViewModel
{
RelevantDate = relevant,
BillableHours = timesheet.BillableHours,
Finished = finished,
Id = timesheet.Id,
StaffMember = timesheet.StaffMember.UserName, // NRE here.
Start = start,
Task = timesheet.Task.Name // NRE here.
});
}
return model;
}
Чтобы исправить это, мне пришлось изменить запрос, извлекающий данные, на следующий:
var timesheets = db.Timesheets.Include(i => i.StaffMember).Include(i => i.Task)
.Where(x => x.Approved && x.Company.Id == companyId && !x.Deleted).ToList();
Почему Entity Framework иногда с радостью предоставляет мне данные, а я явно не запрашиваю эти данные, а иногда мне требуется явно запросить данные, иначе выдается ошибка?
А как мне узнать, когда мне нужно явно включить данные, которые я ищу, а когда нет?