gpt4 book ai didi

c# - 什么时候需要在 Entity Framework 中包含相关实体?

转载 作者:行者123 更新时间:2023-11-30 21:29:21 25 4
gpt4 key购买 nike

当我必须实际 .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

如您所见,公司的信息肯定是通过了,但没有明确包含在内。

没有 .Include() 就无法工作;

相反,我在同一个项目中完成了一些与发票有关的映射,并且在获取相关实体属性值时出现了 NullReferenceExceptions,因为我没有 .Include()

此方法获取指定公司的所有已批准时间表条目。此 View 模型专门用于处理发票的时间表条目的关联(因此您根据所选的时间表条目开具发票)。

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

NullReferenceExceptions 发生在将时间表实体映射到 View 模型的工厂中:

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 有时很乐意在我没有明确请求数据的情况下为我提供数据,而有时却要求我明确请求数据,否则会抛出错误?

我怎么知道什么时候需要明确包含我要查找的数据,什么时候不需要?

最佳答案

Entity Framework 使用延迟加载来加载子关系。 为了延迟加载工作,模型中的属性应该用 virtual 关键字标记。Ef 覆盖它并添加延迟加载支持。

当您没有虚拟属性时,EF 以后无法加载您的子关系数据,因此唯一可能的情况是 - 在初始数据加载期间使用 Include

public class Timesheet
{
...
public virtual StaffMember StaffMember { get; set; }
public virtual Task Task { get; set; }
...
}

关于c# - 什么时候需要在 Entity Framework 中包含相关实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55454839/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com