MVC EF Lazy Loading - Detected at loading?

I have installed lazy loading by model. However, performance still seems a little slow. Is there a way that I can tell exactly when a lazy object is being loaded? I get the impression that it might be a download when I don't want to.

Any help would be greatly appreciated. Let me know if the code samples help - and I'll post them.

Thank.

EDIT:

Here is the relevant code. Essentially, it lists job details. There are buttons for loading timetable data and work data (via ajax). I would expect no timetable data or note entries to be loaded before that (however, after adding the ObjectMaterialized event, it seems to be there);

Controller:

public async Task<ActionResult> Index()
{
    return View(await this._JobRepository.GetActiveByUserAsync(User.Identity.Name));
}

      

Repository:

public async Task<List<JobModel>> GetActiveByUserAsync(string user)
{
    return await this.FindAllAsync(j => (j.AssignedTo.UserName == user || j.JobOwner.UserName == user) && j.Status == 2);
}

public async Task<List<JobModel>> FindAllAsync(Expression<Func<JobModel, bool>> match)
{
    return await this._db.Jobs.Where(match).ToListAsync();
}

      

View:

Index

@using <Namepace>.Models
@model IEnumerable<JobModel>

@{
    ViewBag.Title = "Jobs";
}

<div class="container">
    <section id="searchSection">
        <div class="searchField">
            <div class="searchButton" onclick="searchJob()"></div>
            <div><input id="searchTextBox" placeholder="ID | Name | Description | Customer" title="Search for a job ID, Name, Description or Customer" /></div>
        </div>
    </section>
    <section id="searchResultsSection" style="display:none;">
        <div class="title">Search Results</div>
        <div id="searchResults"></div>
    </section>
    <section id="myJobsSection">
        <div class="title">My Jobs</div>
        @Html.Partial("_JobDetailsListPartial", Model)
    </section>
</div>

@section head {
    @Styles.Render("~/Content/jobDetails.css")
    @Scripts.Render("~/Scripts/jobDetailFunctions.js")
}

      

_JobDetailsListPartial:

@using <Namespace>.Models
@model IEnumerable<JobModel>

<div class="jobListContainer">
    @foreach (JobModel job in Model)
    {
        @Html.Partial("_JobDetailsPartial", job);
    }
</div>
@if (Model.Count() < 1)
{
    <div style="padding:10px 20px 10px 20px;">No Results Found.</div>
}

      

_JobDetailsPartial:

@using <Namespace>.Models
@model JobModel

<section class="jobSection">
    <section class="headerSection">
        <div class="detailField" style="padding-bottom:20px">
            <div class="fieldTitle">@Html.DisplayNameFor(m => m.ID)</div>
            <div>@Html.DisplayFor(m => m.ID)</div>
            <div class="detailButton expandButton" onclick="showHideExpandingSection(this, 'JobDetails')"></div>
        </div>
        <div class="detailField">
            <div class="fieldTitle">@Html.DisplayNameFor(m => m.Name)</div>
            <div>@Html.DisplayFor(m => m.Name)</div>
        </div>
        <div class="detailField">
            <div class="fieldTitle">@Html.DisplayNameFor(m => m.Account)</div>
            <div>@Html.DisplayFor(m => m.Account.Name)</div>
        </div>
    </section>
    <section class="jobDetailsExpandingSection expandingSection" style="display:none;">
        <section style="border-bottom: 1px solid #D8D8D8;">
            <div class="detailField">
                <div>@Html.DisplayNameFor(m => m.StatusName)</div>
                <div>@Html.DisplayFor(m => m.StatusName)</div>
            </div>
            <div class="detailField">
                <div>@Html.DisplayNameFor(m => m.Stage)</div>
                <div>@Html.DisplayFor(m => m.Stage)</div>
            </div>
            <div class="detailField">
                <div>@Html.DisplayNameFor(m => m.Type)</div>
                <div>@Html.DisplayFor(m => m.Type)</div>
            </div>
            <div class="detailField">
               <div>@Html.DisplayNameFor(m => m.Rate.Description)</div>
               <div>@Html.DisplayFor(m => m.Rate.Description)</div>
            </div>
            <div class="detailField">
                <div>@Html.DisplayNameFor(m => m.Rate.RatePerHour)</div>
                <div>$@(Model.Rate.RatePerHour.HasValue ? Html.DisplayFor(m => m.Rate.RatePerHour) : new MvcHtmlString("0.00"))</div>
            </div>
            <div class="detailField">
                <div>@Html.DisplayNameFor(m => m.JobPriority)</div>
                <div>@Html.DisplayFor(m => m.JobPriority)</div>
            </div>
            <div class="detailField">
                <div>@Html.DisplayNameFor(m => m.Account.Owner)</div>
                <div>@Html.DisplayFor(m => m.Account.Owner.Name)</div>
            </div>
            <div class="detailField">
                <div>@Html.DisplayNameFor(m => m.JobOwner)</div>
                <div>@Html.DisplayFor(m => m.JobOwner.Name)</div>
            </div>
            <div class="detailField">
                <div>@Html.DisplayNameFor(m => m.AssignedTo)</div>
                <div>@Html.DisplayFor(m => m.AssignedTo.Name)</div>
            </div>
            <div class="detailField">
                <div>@Html.DisplayNameFor(m => m.ScheduledDate)</div>
                <div>@(Model.ScheduledDate.HasValue ? Html.DisplayFor(m => m.ScheduledDate) : new MvcHtmlString("Not Set"))</div>
            </div>
            <div class="detailField">
                <div>@Html.DisplayNameFor(m => m.StartDate)</div>
                <div>@(Model.StartDate.HasValue ? Html.DisplayFor(m => m.StartDate) : new MvcHtmlString("Not Set"))</div>
           </div>
            <div class="detailField">
                <div>@Html.DisplayNameFor(m => m.DeadlineDate)</div>
                 <div>@(Model.DeadlineDate.HasValue ? Html.DisplayFor(m => m.DeadlineDate) : new MvcHtmlString("Not Set"))</div>
            </div>
            <div class="detailField">
                <div>@Html.DisplayNameFor(m => m.FinishedDate)</div>
                <div>@(Model.FinishedDate.HasValue ? Html.DisplayFor(m => m.FinishedDate) : new MvcHtmlString("Not Set"))</div>
            </div>
        </section>
        <div class="expandingField">
            <div>@Html.DisplayNameFor(m => m.CustomerContact)</div>
            <div class="detailButton expandInnerButton" onclick="showHideExpandingSection(this, 'Contact')"></div>
        </div>
        <section class="customerExpandingSection expandingSection" style="display:none;border-bottom: 1px solid #D8D8D8;">
            <div class="detailField">
                <div>@Html.DisplayNameFor(m => m.CustomerContact.Name)</div>
                <div>@Html.DisplayFor(m => m.CustomerContact.Name)</div>
            </div>
            <div class="detailField">
                <div>@Html.DisplayNameFor(m => m.Address.Address)</div>
                <div>@(!String.IsNullOrEmpty(Model.Address.Address) ? Html.DisplayFor(m => m.Address.Address) : new MvcHtmlString("Not Set"))</div>
            </div>
            <div class="detailField">
                <div>@Html.DisplayNameFor(m => m.Address.City)</div>
                <div>@(!String.IsNullOrEmpty(Model.Address.City) ? Html.DisplayFor(m => m.Address.City) : new MvcHtmlString("Not Set"))</div>
            </div>
            <div class="detailField">
                <div>@Html.DisplayNameFor(m => m.Address.State)</div>
                <div>@(!String.IsNullOrEmpty(Model.Address.State) ? Html.DisplayFor(m => m.Address.State) : new MvcHtmlString("Not Set"))</div>
            </div>
            <div class="detailField">
                <div>@Html.DisplayNameFor(m => m.Address.Country)</div>
                <div>@(!String.IsNullOrEmpty(Model.Address.Country) ? Html.DisplayFor(m => m.Address.Country) : new MvcHtmlString("Not Set"))</div>
            </div>
            <div class="detailField">
                <div>@Html.DisplayNameFor(m => m.Address.PostCode)</div>
                <div>@(!String.IsNullOrEmpty(Model.Address.PostCode) ? Html.DisplayFor(m => m.Address.PostCode) : new MvcHtmlString("Not Set"))</div>
            </div>
            <div class="detailField">
                <div>@Html.DisplayNameFor(m => m.CustomerContact.Phone)</div>
                <div>@(!String.IsNullOrEmpty(Model.CustomerContact.Phone) ? !String.IsNullOrEmpty(Model.CustomerContact.PhoneExtention) ? new MvcHtmlString("(" + Html.DisplayFor(m => m.CustomerContact.PhoneExtention) + ") " + Html.DisplayFor(m => m.CustomerContact.Phone)) : new MvcHtmlString("") : new MvcHtmlString("Not Set"))</div>
            </div>
            <div class="detailField">
                <div>@Html.DisplayNameFor(m => m.CustomerContact.Mobile)</div>
                <div>@(!String.IsNullOrEmpty(Model.CustomerContact.Mobile) ? Html.DisplayFor(m => m.CustomerContact.Mobile) : new MvcHtmlString("Not Set"))</div>
            </div>
            <div class="detailField">
                <div>@Html.DisplayNameFor(m => m.CustomerContact.Email)</div>
                <div>@(!String.IsNullOrEmpty(Model.CustomerContact.Email) ? Html.DisplayFor(m => m.CustomerContact.Email) : new MvcHtmlString("Not Set"))</div>
            </div>
        </section>
        <div class="expandingField">
            <div>@Html.DisplayNameFor(m => m.Description)</div>
            <div class="detailButton expandInnerButton" onclick="showHideExpandingSection(this, 'JobDescription')"></div>
        </div>
        <section class="jobDescriptionExpandingSection expandingSection" style="display:none;border-bottom: 1px solid #D8D8D8;">
            <div class="detailField">
                <div>@Html.DisplayNameFor(m => m.Description)</div>
                <div style="white-space: pre-line">@(!String.IsNullOrEmpty(Model.Description) ? Html.DisplayFor(m => m.Description) : new MvcHtmlString("Not Set"))</div>
            </div>
        </section>

        <div class="expandingField">
            <div>@Html.DisplayNameFor(m => m.Timesheets)</div>
            <div class="detailButton expandInnerButton" onclick="showHideExpandingSection(this, 'JobTimesheets', @Model.ID)"></div>
        </div>
        <section id="TimesheetSection_@Model.ID" class="jobTimesheetsExpandingSection expandingSection" style="display:none;"></section>

        <div class="expandingField">
            <div>@Html.DisplayNameFor(m => m.JobNotes)</div>
            <div class="detailButton expandInnerButton" onclick="showHideExpandingSection(this, 'JobNotes', @Model.ID)"></div>
        </div>
        <section class="jobNotesExpandingSection expandingSection" style="display:none;"></section>
    </section>
</section>

      

Model:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace <Namespace>.Models
{
    [Table("v_ITQJobs")]
    public partial class JobModel
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        [Display(Name = "Job ID:")]
        [Column("JOBID")]
        public int ID { get; set; }

        [Display(Name = "Job Name:")]
        [Column("JOBNAME")]
        public string Name { get; set; }

        [Column("ACCOUNTID")]
        public int? AccountID { get; set; }

        [Display(Name = "Customer:")]
        public virtual CustomerModel Account { get; set; }

        [Display(Name = "Job Description:")]
        [Column("DESCRIPTION")]
        public string Description { get; set; }

        [Column("JOBOWNERID")]
        public int? JobOwnerID { get; set; }

        [Display(Name = "Owned By:")]
        public virtual EmployeeModel JobOwner { get; set; }

        [Column("USERID")]
        public int? AssignedToID { get; set; }

        [Display(Name = "Assigned To:")]
        public virtual EmployeeModel AssignedTo { get; set; }

        [Column("STATUSID")]
        public int? Status { get; set; }

        [Display(Name = "Status:")]
        [Column("STATUSNAME")]
        public string StatusName { get; set; }

        [Display(Name = "Stage:")]
        [Column("STAGENAME")]
        public string Stage { get; set; }

        [Display(Name = "Type:")]
        [Column("TYPENAME")]
        public string Type { get; set; }

        public RateModel Rate { get; set; }

        [Display(Name = "Priority:")]
        [Column("JOBPRIORITY")]
        public string JobPriority { get; set; }

        [Column("SCHEDULEDDATETIME")]
        [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy HH:mm}")]
        [Display(Name = "Scheduled Date:")]
        public DateTime? ScheduledDate { get; set; }

        [Column("STARTDATETIME")]
        [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy HH:mm}")]
        [Display(Name = "Start Date:")]
        public DateTime? StartDate { get; set; }

        [Column("ETADATETIME")]
        [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy HH:mm}")]
        [Display(Name = "Deadline Date:")]
        public DateTime? DeadlineDate { get; set; }

        [Column("FINISHEDDATETIME")]
        [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy HH:mm}")]
        [Display(Name = "Finish Date:")]
        public DateTime? FinishedDate { get; set; }

        [Column("CONTACTID")]
        public int? ContactID { get; set; }

        [Display(Name = "Customer Contact")]
        public virtual ContactModel CustomerContact { get; set; }

        public AddressModel Address { get; set; }

        [Display(Name = "Timesheets")]
        public virtual ICollection<TimesheetModel> Timesheets { get; set; }

        [Display(Name = "Job Notes")]
        public virtual ICollection<ITQJobNoteModel> JobNotes { get; set; }

        [Column("ISGLOBAL")]
        public bool IsGlobal { get; set; }

        [NotMapped]
        public string GroupName {
            get
            {
                return this.IsGlobal ? "Global Jobs" : "My Jobs";
            }
        }

        [NotMapped]
        public string Caption
        {
            get
            {
                if (this.ID != default(int))
                    return String.Format("{0} - {1}", this.ID, this.Name);
                else
                    return null;
            }
        }

        public JobModel()
        {
            this.JobNotes = new HashSet<ITQJobNoteModel>();
            this.Timesheets = new HashSet<TimesheetModel>();
        }
    }
}

      

How can I prevent them from loading until I want to?

+3


source to share


1 answer


You can use the ObjectContext.ObjectMaterialized

event and subscribe in the constructor DbContext

.

((IObjectContextAdapter)yourDbContext).ObjectContext.ObjectMaterialized += HandlerFunction;

      



See also: Where to subscribe to ObjectMaterialized with EF6?

0


source







All Articles