Aracılığıyla paylaş


Öğretici: ASP.NET MVC uygulamasında EF ile ilgili verileri okuma

Önceki öğreticide School veri modelini tamamladınız. Bu öğreticide ilgili verileri ( yani Entity Framework'ün gezinti özelliklerine yüklediğini) okuyacak ve görüntüleyeceksiniz.

Aşağıdaki çizimlerde, çalışacağınız sayfalar gösterilmektedir.

Kursların listesini içeren Kurslar sayfasını gösteren ekran görüntüsü.

Instructors_index_page_with_instructor_and_course_selected

Tamamlanan Projeyi İndir

Contoso University örnek web uygulaması, Entity Framework 6 Code First ve Visual Studio kullanarak ASP.NET MVC 5 uygulamalarının nasıl oluşturulacağını gösterir. Öğretici serisi hakkında bilgi için serideki ilk öğreticiye bakın.

Bu öğreticide şunları yaptınız:

  • İlgili verileri yüklemeyi öğrenin
  • Kurslar sayfası oluşturma
  • Eğitmenler sayfası oluşturma

Önkoşullar

Entity Framework'ün ilgili verileri bir varlığın gezinti özelliklerine yüklemesinin çeşitli yolları vardır:

  • Yavaş yükleme. Varlık ilk okunduğunda ilgili veriler alınmaz. Ancak, bir gezinti özelliğine ilk kez erişmeye çalıştığınızda, bu gezinti özelliği için gereken veriler otomatik olarak alınır. Bu, veritabanına birden çok sorgu gönderilmesiyle sonuçlanır. Bunlardan biri varlığın kendisi için, diğeri de varlıkla ilgili verilerin her alınması gerektiğinde alınır. DbContext sınıfı varsayılan olarak gecikmeli yüklemeyi etkinleştirir.

    Lazy_loading_example

  • İstekli yükleme. Varlık okunduğunda, onunla birlikte ilgili veriler de alınır. Bu genellikle gereken tüm verileri alan tek bir birleştirme sorgusuyla sonuçlanmıştır. yöntemini kullanarak Include istekli yükleme belirtirsiniz.

    Eager_loading_example

  • Açık yükleme. Bu, koddaki ilgili verileri açıkça almanız dışında gecikmeli yüklemeye benzer; bir gezinti özelliğine eriştiğinde otomatik olarak gerçekleşmez. Bir varlığın nesne durumu yöneticisi girdisini alıp koleksiyonlar için Collection.Load yöntemini veya tek bir varlığı barındıran özellikler için Reference.Load yöntemini çağırarak ilgili verileri el ile yüklersiniz. (Aşağıdaki örnekte, Yönetici gezinti özelliğini yüklemek isterseniz değerini ile Reference(x => x.Administrator)değiştirirsinizCollection(x => x.Courses).) Genellikle açık yüklemeyi yalnızca gecikmeli yüklemeyi kapattığınızda kullanırsınız.

    Explicit_loading_example

Özellik değerlerini hemen almadıkları için gecikmeli yükleme ve açık yükleme de ertelenmiş yükleme olarak bilinir.

Performansla ilgili önemli noktalar

Alınan her varlık için ilgili verilere ihtiyacınız olduğunu biliyorsanız, veritabanına gönderilen tek bir sorgu genellikle alınan her varlık için ayrı sorgulardan daha verimli olduğundan, istekli yükleme genellikle en iyi performansı sunar. Örneğin, yukarıdaki örneklerde her departmanın on ilgili kursu olduğunu varsayalım. İstekli yükleme örneği yalnızca tek bir (birleştirme) sorgusuna ve veritabanına tek bir gidiş dönüşe neden olur. Yavaş yükleme ve açık yükleme örnekleri hem on bir sorguya hem de veritabanına on bir gidiş dönüşe neden olur. Veritabanına yapılan ek gidiş dönüşler, özellikle gecikme süresi yüksek olduğunda performansa zarar vericidir.

Öte yandan, bazı senaryolarda gecikmeli yükleme daha verimlidir. Hızlı yükleme, çok karmaşık bir birleştirmenin oluşturulmasına neden olabilir ve SQL Server verimli bir şekilde işlem yapamaz. Öte yandan, bir varlığın gezinti özelliklerine yalnızca işlemekte olduğunuz varlık kümesinin bir alt kümesi için erişmeniz gerekiyorsa, istekli yükleme ihtiyacınızdan daha fazla veri alacağından gecikmeli yükleme daha iyi performans gösterebilir. Performans kritikse, en iyi seçimi yapmak için performansı her iki yolla da test etmek en iyisidir.

Yavaş yükleme, performans sorunlarına neden olan kodu maskeleyebilir. Örneğin, istekli veya açık yükleme belirtmeyen ancak yüksek hacimli varlıkları işleyen ve her yinelemede çeşitli gezinti özellikleri kullanan kod çok verimsiz olabilir (veritabanına yapılan birçok gidiş dönüş nedeniyle). Şirket içi SQL sunucusu kullanarak geliştirme aşamasında iyi performans gösteren bir uygulama, artan gecikme süresi ve gecikmeli yükleme nedeniyle Azure SQL Veritabanına taşındığında performans sorunları yaşayabilir. Gerçekçi bir test yüküyle veritabanı sorgularının profilini oluşturmak gecikmeli yüklemenin uygun olup olmadığını belirlemenize yardımcı olur. Daha fazla bilgi için bkz. Entity Framework Stratejilerini Kaldırma: İlgili Verileri Yükleme ve Ağ Gecikme süresini azaltmak için Entity Framework'ün SQL Azure kullanma.

Serileştirmeden önce gecikmeli yüklemeyi devre dışı bırakma

Serileştirme sırasında gecikmeli yüklemeyi etkin bırakırsanız, istediğinizden çok daha fazla veriyi sorgulayabilirsiniz. Serileştirme genellikle türün bir örneğindeki her özelliğe erişerek çalışır. Özellik erişimi gecikmeli yüklemeyi tetikler ve bu gecikmeli yüklenen varlıklar seri hale getirilir. Serileştirme işlemi daha sonra gecikmeli yüklenen varlıkların her özelliğine erişerek daha da gecikmeli yükleme ve serileştirmeye neden olur. Bu kaçma zinciri tepkisini önlemek için, bir varlığı seri hale getirmeden önce gecikmeli yüklemeyi kapatın.

Serileştirme, Gelişmiş Senaryolar öğreticisinde açıklandığı gibi Entity Framework'ün kullandığı ara sunucu sınıfları tarafından da karmaşık olabilir.

Entity Framework ile Web API'sini Kullanma öğreticisinde gösterildiği gibi, serileştirme sorunlarını önlemenin bir yolu varlık nesneleri yerine veri aktarımı nesnelerini (DTO' lar) seri hale getirmektir.

DTO'ları kullanmıyorsanız, ara sunucu oluşturmayı devre dışı bırakarak gecikmeli yüklemeyi devre dışı bırakabilir ve ara sunucu sorunlarını önleyebilirsiniz.

Yavaş yüklemeyi devre dışı bırakmanın diğer bazı yolları şunlardır:

  • Belirli gezinti özellikleri için, özelliğini bildirirken anahtar sözcüğünü atlar virtual .

  • Tüm gezinti özellikleri için falseolarak ayarlayın LazyLoadingEnabled ve bağlam sınıfınızın oluşturucusunda aşağıdaki kodu yerleştirin:

    this.Configuration.LazyLoadingEnabled = false;
    

Kurslar sayfası oluşturma

Varlık, Course kursun Department atandığı bölümün varlığını içeren bir gezinti özelliği içerir. Atanan bölümün adını bir kurs listesinde görüntülemek için, gezinti özelliğindeki Course.Department varlıktan Department özelliğini almanız Name gerekir.

Daha önce denetleyici için yaptığınız Entity Framework iskelesini Coursekullanarak, görünümlere sahip MVC 5 Denetleyicisi için aynı seçenekleri kullanarak varlık türü için Student (CoursesController değil) adlı CourseController bir denetleyici oluşturun:

Ayar Değer
Model sınıfı Kurs (ContosoUniversity.Models) öğesini seçin.
Veri bağlamı sınıfı SchoolContext (ContosoUniversity.DAL) öğesini seçin.
Denetleyici adı CourseController girin. Yine, bir s ile CoursesController değil. Kurs (ContosoUniversity.Models) öğesini seçtiğinizde Denetleyici adı değeri otomatik olarak doldurulur. Değeri değiştirmeniz gerekir.

Diğer varsayılan değerleri bırakın ve denetleyiciyi ekleyin.

Controllers\CourseController.cs dosyasını açın ve yöntemine Index bakın:

public ActionResult Index()
{
    var courses = db.Courses.Include(c => c.Department);
    return View(courses.ToList());
}

Otomatik yapı iskelesi, yöntemini kullanarak gezinti özelliği için Department istekli yükleme belirtti Include .

Views\Course\Index.cshtml dosyasını açın ve şablon kodunu aşağıdaki kodla değiştirin. Değişiklikler vurgulanır:

@model IEnumerable<ContosoUniversity.Models.Course>

@{
    ViewBag.Title = "Courses";
}

<h2>Courses</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.CourseID)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Title)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Credits)
        </th>
        <th>
            Department
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.CourseID)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Title)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Credits)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Department.Name)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.CourseID }) |
            @Html.ActionLink("Details", "Details", new { id=item.CourseID }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.CourseID })
        </td>
    </tr>
}

</table>

yapı iskelesi oluşturulan kodda aşağıdaki değişiklikleri yaptınız:

  • Dizin başlığı Kurslar olarak değiştirildi.
  • Özellik değerini gösteren CourseID bir Sayı sütunu eklendi. Varsayılan olarak, birincil anahtarlar yapı iskelesi oluşturmaz çünkü normalde son kullanıcılar için anlamsızdır. Ancak, bu durumda birincil anahtar anlamlıdır ve bunu göstermek istersiniz.
  • Department sütununu sağ tarafa taşımış ve başlığını değiştirmiştir. Yapı iskelesi varlığın NameDepartment özelliğini doğru bir şekilde görüntülemeyi seçti, ancak burada Kurs sayfasında sütun başlığı Ad yerine Departman olmalıdır.

Department sütununda, iskelesi oluşturulan kodun gezinti özelliğine Name yüklenen varlığın özelliğini Department görüntülediğine Department dikkat edin:

<td>
    @Html.DisplayFor(modelItem => item.Department.Name)
</td>

Bölüm adlarını içeren listeyi görmek için sayfayı çalıştırın (Contoso Üniversitesi giriş sayfasındaki Kurslar sekmesini seçin).

Eğitmenler sayfası oluşturma

Bu bölümde Eğitmenler sayfasını görüntülemek için varlık için Instructor bir denetleyici ve görünüm oluşturacaksınız. Bu sayfa, ilgili verileri aşağıdaki yollarla okur ve görüntüler:

  • Eğitmenler listesi varlıkla OfficeAssignment ilgili verileri görüntüler. Instructor ve OfficeAssignment varlıkları bire sıfıra veya bir ilişkisindedir. Varlıklar için OfficeAssignment istekli yükleme kullanacaksınız. Daha önce açıklandığı gibi, birincil tablonun tüm alınan satırları için ilgili verilere ihtiyacınız olduğunda, istekli yükleme genellikle daha verimlidir. Bu durumda, görüntülenen tüm eğitmenlerin ofis ödevlerini görüntülemek istiyorsunuz.
  • Kullanıcı bir eğitmen seçtiğinde ilgili Course varlıklar görüntülenir. Instructor ve Course varlıkları çoka çok ilişkisindedir. Varlıklar ve ilgili Department varlıkları için Course istekli yükleme kullanacaksınız. Bu durumda, yalnızca seçilen eğitmen için kurslara ihtiyacınız olduğundan tembel yükleme daha verimli olabilir. Ancak bu örnekte, gezinti özelliklerinde kendileri olan varlıklardaki gezinti özellikleri için istekli yüklemenin nasıl kullanılacağı gösterilmektedir.
  • Kullanıcı bir kurs seçtiğinde varlık kümesindeki Enrollments ilgili veriler görüntülenir. Course ve Enrollment varlıkları bire çok ilişkisindedir. Varlıklar ve ilgili Student varlıklar için Enrollment açık yükleme ekleyeceksiniz. (Gecikmeli yükleme etkinleştirildiğinden açık yükleme gerekli değildir, ancak bu açıkça yüklemenin nasıl yapılacağını gösterir.)

Eğitmen Dizin Görünümü için Görünüm Modeli Oluşturma

Eğitmenler sayfasında üç farklı tablo gösterilir. Bu nedenle, her biri tablolardan birine ait verileri tutan üç özellik içeren bir görünüm modeli oluşturacaksınız.

ViewModels klasöründe InstructorIndexData.cs dosyasını oluşturun ve mevcut kodu aşağıdaki kodla değiştirin:

using System.Collections.Generic;
using ContosoUniversity.Models;

namespace ContosoUniversity.ViewModels
{
    public class InstructorIndexData
    {
        public IEnumerable<Instructor> Instructors { get; set; }
        public IEnumerable<Course> Courses { get; set; }
        public IEnumerable<Enrollment> Enrollments { get; set; }
    }
}

Eğitmen Denetleyicisi ve Görünümleri Oluşturma

EF okuma/yazma eylemiyle bir InstructorController (InstructorsController değil) denetleyicisi oluşturun:

Ayar Değer
Model sınıfı Eğitmen (ContosoUniversity.Models) öğesini seçin.
Veri bağlamı sınıfı SchoolContext (ContosoUniversity.DAL) öğesini seçin.
Denetleyici adı InstructorController yazın. Yine, bir s ile InstructorsController değil. Kurs (ContosoUniversity.Models) öğesini seçtiğinizde Denetleyici adı değeri otomatik olarak dolduruldu. Değeri değiştirmeniz gerekir.

Diğer varsayılan değerleri bırakın ve denetleyiciyi ekleyin.

Controllers\InstructorController.cs dosyasını açın ve ad alanı için ViewModels bir using deyim ekleyin:

using ContosoUniversity.ViewModels;

yöntemindeki Index yapı iskelesi oluşturulmuş kod, yalnızca gezinti özelliği için OfficeAssignment istekli yüklemeyi belirtir:

public ActionResult Index()
{
    var instructors = db.Instructors.Include(i => i.OfficeAssignment);
    return View(instructors.ToList());
}

Index ek ilgili verileri yüklemek ve görünüm modeline yerleştirmek için yöntemini aşağıdaki kodla değiştirin:

public ActionResult Index(int? id, int? courseID)
{
    var viewModel = new InstructorIndexData();
    viewModel.Instructors = db.Instructors
        .Include(i => i.OfficeAssignment)
        .Include(i => i.Courses.Select(c => c.Department))
        .OrderBy(i => i.LastName);

    if (id != null)
    {
        ViewBag.InstructorID = id.Value;
        viewModel.Courses = viewModel.Instructors.Where(
            i => i.ID == id.Value).Single().Courses;
    }

    if (courseID != null)
    {
        ViewBag.CourseID = courseID.Value;
        viewModel.Enrollments = viewModel.Courses.Where(
            x => x.CourseID == courseID).Single().Enrollments;
    }

    return View(viewModel);
}

yöntemi, seçilen eğitmenin ve seçilen kursun kimlik değerlerini sağlayan isteğe bağlı yol verilerini (id) ve sorgu dizesi parametresini (courseID) kabul eder ve tüm gerekli verileri görünüme geçirir. Parametreler sayfadaki Köprü seç seçeneği tarafından sağlanır.

Kod, görünüm modelinin bir örneğini oluşturup eğitmen listesine ekleyerek başlar. Kod, ve Instructor.Courses gezinti özelliği için Instructor.OfficeAssignment istekli yüklemeyi belirtir.

var viewModel = new InstructorIndexData();
viewModel.Instructors = db.Instructors
    .Include(i => i.OfficeAssignment)
    .Include(i => i.Courses.Select(c => c.Department))
     .OrderBy(i => i.LastName);

İkinci Include yöntem Courses'ı yükler ve yüklenen her Kurs için gezinti özelliği için Course.Department istekli yükleme yapar.

.Include(i => i.Courses.Select(c => c.Department))

Daha önce belirtildiği gibi, istekli yükleme gerekli değildir, ancak performansı artırmak için yapılır. Görünüm her zaman varlığı gerektirdiğinden OfficeAssignment , aynı sorguda bunu getirmek daha verimlidir. Course varlıklar, web sayfasında bir eğitmen seçildiğinde gereklidir, bu nedenle istekli yükleme, yalnızca sayfa seçili bir kursta değil de daha sık görüntülendiğinde gecikmeli yüklemeden daha iyidir.

Eğitmen kimliği seçilmişse, seçilen eğitmen görünüm modelindeki eğitmenler listesinden alınır. Ardından görünüm modelinin Courses özelliği, eğitmenin CourseCourses gezinti özelliğindeki varlıklarla birlikte yüklenir.

if (id != null)
{
    ViewBag.InstructorID = id.Value;
    viewModel.Courses = viewModel.Instructors.Where(i => i.ID == id.Value).Single().Courses;
}

Where yöntemi bir koleksiyon döndürür, ancak bu durumda bu yönteme geçirilen ölçütler yalnızca tek Instructor bir varlığın döndürülmesine neden olur. yöntemi, Single koleksiyonu tek Instructor bir varlığa dönüştürür ve bu sayede bu varlığın Courses özelliğine erişmenizi sağlar.

Koleksiyonun yalnızca bir öğeye sahip olacağını bildiğinizde bir koleksiyonda Single yöntemini kullanırsınız. yöntemi, Single geçirilen koleksiyon boşsa veya birden fazla öğe varsa bir özel durum oluşturur. Alternatif olarak, koleksiyon boşsa varsayılan bir değer (nullbu örnekte) döndüren SingleOrDefault kullanılabilir. Ancak, bu durumda bu durum yine de bir özel durumla sonuçlanır (başvuruda null bir Courses özelliği bulmaya çalışırken) ve özel durum iletisi sorunun nedenini daha az net bir şekilde gösterir. yöntemini çağırdığınızdaSingle, yöntemi ayrı olarak çağırmak Where yerine koşulu da Where geçirebilirsiniz:

.Single(i => i.ID == id.Value)

Onun yerine:

.Where(I => i.ID == id.Value).Single()

Daha sonra, bir kurs seçildiyse, seçilen kurs görünüm modelindeki kurs listesinden alınır. Ardından görünüm modelinin Enrollments özelliği, bu kursun EnrollmentEnrollments gezinti özelliğindeki varlıklarla birlikte yüklenir.

if (courseID != null)
{
    ViewBag.CourseID = courseID.Value;
    viewModel.Enrollments = viewModel.Courses.Where(
        x => x.CourseID == courseID).Single().Enrollments;
}

Eğitmen Dizin Görünümünü Değiştirme

Views\Instructor\Index.cshtml içinde şablon kodunu aşağıdaki kodla değiştirin. Değişiklikler vurgulanır:

@model ContosoUniversity.ViewModels.InstructorIndexData

@{
    ViewBag.Title = "Instructors";
}

<h2>Instructors</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table class="table">
    <tr>
        <th>Last Name</th>
        <th>First Name</th>
        <th>Hire Date</th>
        <th>Office</th>
        <th></th>
    </tr>

    @foreach (var item in Model.Instructors)
    {
        string selectedRow = "";
        if (item.ID == ViewBag.InstructorID)
        {
            selectedRow = "success";
        }
        <tr class="@selectedRow">
            <td>
                @Html.DisplayFor(modelItem => item.LastName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.FirstMidName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.HireDate)
            </td>
            <td>
                @if (item.OfficeAssignment != null)
                {
                    @item.OfficeAssignment.Location
                }
            </td>
            <td>
                @Html.ActionLink("Select", "Index", new { id = item.ID }) |
                @Html.ActionLink("Edit", "Edit", new { id = item.ID }) |
                @Html.ActionLink("Details", "Details", new { id = item.ID }) |
                @Html.ActionLink("Delete", "Delete", new { id = item.ID })
            </td>
        </tr>
    }

    </table>

Mevcut kodda aşağıdaki değişiklikleri yaptınız:

  • Model sınıfı olarak InstructorIndexDatadeğiştirildi.

  • Dizin olan sayfa başlığı Eğitmenler olarak değiştirildi.

  • Yalnızca null değilse item.OfficeAssignment görüntülenen item.OfficeAssignment.Location bir Office sütunu eklendi. (Bu bire sıfıra veya bir ilişkisi olduğundan, ilgili OfficeAssignment bir varlık olmayabilir.)

    <td> 
        @if (item.OfficeAssignment != null) 
        { 
            @item.OfficeAssignment.Location  
        } 
    </td>
    
  • Seçili eğitmenin tr öğesine dinamik olarak eklenecek kod eklendiclass="success". Bu, Bootstrap sınıfını kullanarak seçili satır için bir arka plan rengi ayarlar.

    string selectedRow = ""; 
    if (item.InstructorID == ViewBag.InstructorID) 
    { 
        selectedRow = "success"; 
    } 
    <tr class="@selectedRow" valign="top">
    
  • Her satırdaki diğer bağlantılardan hemen önce Seç etiketli yeni ActionLink bir etiket eklendi ve bu da seçilen eğitmen kimliğinin yönteme gönderilmesine Index neden oluyor.

Uygulamayı çalıştırın ve Eğitmenler sekmesini seçin. Sayfa, ilişkili varlık olmadığında OfficeAssignment ilgili OfficeAssignment varlıkların ve boş bir tablo hücresinin özelliğini görüntülerLocation.

Views\Instructor\Index.cshtml dosyasında, kapanış table öğesinden sonra (dosyanın sonuna) aşağıdaki kodu ekleyin. Bu kod, bir eğitmen seçildiğinde eğitmenle ilgili derslerin listesini görüntüler.

@if (Model.Courses != null)
{
    <h3>Courses Taught by Selected Instructor</h3>
    <table class="table">
        <tr>
            <th></th>
            <th>Number</th>
            <th>Title</th>
            <th>Department</th>
        </tr>

        @foreach (var item in Model.Courses)
        {
            string selectedRow = "";
            if (item.CourseID == ViewBag.CourseID)
            {
                selectedRow = "success";
            }
            <tr class="@selectedRow">
                <td>
                    @Html.ActionLink("Select", "Index", new { courseID = item.CourseID })
                </td>
                <td>
                    @item.CourseID
                </td>
                <td>
                    @item.Title
                </td>
                <td>
                    @item.Department.Name
                </td>
            </tr>
        }

    </table>
}

Bu kod, kurs listesini Courses görüntülemek için görünüm modelinin özelliğini okur. Ayrıca, seçili kursun kimliğini eylem yöntemine Index gönderen bir Select köprü sağlar.

Sayfayı çalıştırın ve bir eğitmen seçin. Artık seçili eğitmene atanan dersleri gösteren bir kılavuz görürsünüz ve her kurs için atanan bölümün adını görürsünüz.

Yeni eklediğiniz kod bloğundan sonra aşağıdaki kodu ekleyin. Bu, bir kurs seçildiğinde bir kursa kaydolan öğrencilerin listesini görüntüler.

@if (Model.Enrollments != null)
{
    <h3>
        Students Enrolled in Selected Course
    </h3>
    <table class="table">
        <tr>
            <th>Name</th>
            <th>Grade</th>
        </tr>
        @foreach (var item in Model.Enrollments)
        {
            <tr>
                <td>
                    @item.Student.FullName
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Grade)
                </td>
            </tr>
        }
    </table>
}

Bu kod, kursa Enrollments kayıtlı öğrencilerin listesini görüntülemek için görünüm modelinin özelliğini okur.

Sayfayı çalıştırın ve bir eğitmen seçin. Ardından kayıtlı öğrencilerin listesini ve notlarını görmek için bir kurs seçin.

Açık Yükleme Ekleme

InstructorController.cs dosyasını açın ve yöntemin Index seçilen kursun kayıt listesini nasıl aldığına bakın:

if (courseID != null)
{
    ViewBag.CourseID = courseID.Value;
    viewModel.Enrollments = viewModel.Courses.Where(
        x => x.CourseID == courseID).Single().Enrollments;
}

Eğitmen listesini aldığınızda gezinti özelliği ve her kursun Courses özelliği için Department istekli yükleme belirttiniz. Ardından koleksiyonu görünüm modeline Courses yerleştirirsiniz ve şimdi bu koleksiyondaki Enrollments bir varlıktan gezinti özelliğine erişiyor olursunuz. Gezinti özelliği için hevesle yüklemeyi belirtmediğiniz için Course.Enrollments , bu özellikteki veriler gecikmeli yüklemenin bir sonucu olarak sayfada görüntülenir.

Kodu başka bir şekilde değiştirmeden gecikmeli yüklemeyi devre dışı bırakırsanız, kursun Enrollments gerçekte kaç kaydı olduğuna bakılmaksızın özellik null olur. Bu durumda, özelliği yüklemek Enrollments için istekli yükleme veya açık yükleme belirtmeniz gerekir. İstekli yüklemeyi nasıl yapacağınızı zaten gördünüz. Açık yükleme örneğini görmek için yöntemini özelliğini açıkça yükleyen Enrollments aşağıdaki kodla değiştirinIndex. Değiştirilen kod vurgulanır.

public ActionResult Index(int? id, int? courseID)
{
    var viewModel = new InstructorIndexData();

    viewModel.Instructors = db.Instructors
        .Include(i => i.OfficeAssignment)
        .Include(i => i.Courses.Select(c => c.Department))
        .OrderBy(i => i.LastName);

    if (id != null)
    {
        ViewBag.InstructorID = id.Value;
        viewModel.Courses = viewModel.Instructors.Where(
            i => i.ID == id.Value).Single().Courses;
    }
    
    if (courseID != null)
    {
        ViewBag.CourseID = courseID.Value;
        // Lazy loading
        //viewModel.Enrollments = viewModel.Courses.Where(
        //    x => x.CourseID == courseID).Single().Enrollments;
        // Explicit loading
        var selectedCourse = viewModel.Courses.Where(x => x.CourseID == courseID).Single();
        db.Entry(selectedCourse).Collection(x => x.Enrollments).Load();
        foreach (Enrollment enrollment in selectedCourse.Enrollments)
        {
            db.Entry(enrollment).Reference(x => x.Student).Load();
        }

        viewModel.Enrollments = selectedCourse.Enrollments;
    }

    return View(viewModel);
}

Seçilen Course varlığı aldıktan sonra yeni kod, bu kursun Enrollments gezinti özelliğini açıkça yükler:

db.Entry(selectedCourse).Collection(x => x.Enrollments).Load();

Ardından her Enrollment varlığın ilgili Student varlığını açıkça yükler:

db.Entry(enrollment).Reference(x => x.Student).Load();

Bir koleksiyon özelliğini yüklemek için yöntemini kullandığınıza Collection , ancak tek bir varlığı barındıran bir özellik için yöntemini kullandığınıza Reference dikkat edin.

Eğitmen Dizini sayfasını şimdi çalıştırdığınızda, verilerin nasıl alındığını değiştirmiş olmanıza rağmen sayfada görüntülenenler arasında bir fark görmezsiniz.

Kodu alma

Tamamlanan Projeyi İndir

Ek kaynaklar

Diğer Entity Framework kaynaklarına bağlantılar ASP.NET Veri Erişimi - Önerilen Kaynaklar bölümünde bulunabilir.

Sonraki adımlar

Bu öğreticide şunları yaptınız:

  • İlgili verileri yüklemeyi öğrendin
  • Kurslar sayfası oluşturuldu
  • Eğitmenler sayfası oluşturuldu

İlgili verileri nasıl güncelleştireceğinizi öğrenmek için sonraki makaleye ilerleyin.