为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
潇潇雨雨 2022-11-21 20:18:06
当我必须实际.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.    }}下面是结果,其中包括与我要求的发票相关的公司数据:如您所见,公司的信息肯定是通过了,但没有明确包含在内。没有 .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);}要解决这些问题,我必须将获取数据的查询更改为以下内容: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 有时很乐意在我没有明确请求数据的情况下为我提供数据,有时却要求我明确请求数据,否则会抛出错误?我怎么知道什么时候需要明确包含我正在寻找的数据,什么时候不需要?
查看完整描述

2 回答

?
慕丝7291255

TA贡献1859条经验 获得超6个赞

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


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


public class Timesheet

{

    ...

    public virtual StaffMember StaffMember { get; set; }

    public virtual Task Task { get; set; }

    ...

}


查看完整回答
反对 回复 2022-11-21
?
眼眸繁星

TA贡献1873条经验 获得超9个赞

这取决于你的模型。如果您已将关系属性标记为,virtual那么您将需要使用.Include它,以便 EF 知道您需要它。这是延迟加载。保留机器的内存和数据库请求。



查看完整回答
反对 回复 2022-11-21
  • 2 回答
  • 0 关注
  • 67 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信