Aracılığıyla paylaş


MVC Web Uygulaması için Gelişmiş Entity Framework Senaryoları (10/10)

tarafından Tom Dykstra

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

Not

Çözemediğiniz bir sorunla karşılaşırsanız tamamlanmış bölümü indirin ve sorununuzu yeniden oluşturmayı deneyin. Genellikle kodunuzu tamamlanmış kodla karşılaştırarak sorunun çözümünü bulabilirsiniz. Bazı yaygın hatalar ve bunların nasıl çözüldüğü için bkz . Hatalar ve Geçici Çözümler.

Önceki öğreticide depoyu ve iş desenleri birimini uyguladınız. Bu öğretici aşağıdaki konuları kapsar:

  • Ham SQL sorguları gerçekleştirme.
  • İzleme olmayan sorgular gerçekleştirme.
  • Veritabanına gönderilen sorguları inceleme.
  • Ara sunucu sınıfları ile çalışma.
  • Değişikliklerin otomatik algılanması devre dışı bırakılmaktadır.
  • Değişiklikleri kaydederken doğrulamayı devre dışı bırakma.
  • Hatalar ve Geçici Çözüm

Bu konuların çoğu için önceden oluşturduğunuz sayfalarla çalışacaksınız. Toplu güncelleştirmeler yapmak için ham SQL kullanmak için veritabanındaki tüm kursların kredi sayısını güncelleştiren yeni bir sayfa oluşturacaksınız:

Kurs Kredilerini Güncelleştir başlangıç sayfasını gösteren ekran görüntüsü. Metin alanına 2 sayısı girilir.

İzleme olmayan bir sorgu kullanmak için Bölüm Düzenleme sayfasına yeni doğrulama mantığı ekleyeceksiniz:

Yinelenen yönetici hata iletisini içeren Contoso Üniversitesi Bölümü Düzenleme sayfasını gösteren ekran görüntüsü.

Ham SQL Sorguları Gerçekleştirme

Entity Framework Code First API'sinde SQL komutlarını doğrudan veritabanına geçirmenizi sağlayan yöntemler bulunur. Aşağıdaki seçenekler mevcuttur:

  • DbSet.SqlQuery Varlık türlerini döndüren sorgular için yöntemini kullanın. Döndürülen nesneler nesne tarafından DbSet beklenen türde olmalıdır ve izlemeyi kapatmadığınız sürece veritabanı bağlamı tarafından otomatik olarak izlenir. (Yöntemi hakkında aşağıdaki bölüme AsNoTracking bakın.)
  • Database.SqlQuery Varlık olmayan türler döndüren sorgular için yöntemini kullanın. Varlık türlerini almak için bu yöntemi kullansanız bile döndürülen veriler veritabanı bağlamı tarafından izlenmez.
  • Sorgu olmayan komutlar için Database.ExecuteSqlCommand kullanın.

Entity Framework kullanmanın avantajlarından biri, kodunuzu belirli bir veri depolama yöntemine çok yakın bağlamaktan kaçınmasıdır. Bunu, sizin için SQL sorguları ve komutları oluşturarak yapar ve bu da bunları kendiniz yazmaktan da kurtulmuş olursunuz. Ancak el ile oluşturduğunuz belirli SQL sorgularını çalıştırmanız gerektiğinde olağanüstü senaryolar vardır ve bu yöntemler bu tür özel durumları işlemenizi mümkün kılar.

Bir web uygulamasında SQL komutlarını yürütürken her zaman olduğu gibi sitenizi SQL ekleme saldırılarına karşı korumak için önlemler almanız gerekir. Bunu yapabilmenin bir yolu, bir web sayfası tarafından gönderilen dizelerin SQL komutları olarak yorumlanamamasını sağlamak için parametreli sorgular kullanmaktır. Bu öğreticide kullanıcı girişini sorguyla tümleştirirken parametreli sorgular kullanacaksınız.

Varlıkları Döndüren Bir Sorguyu Çağırma

Sınıfın GenericRepository ek yöntemlerle türetilmiş bir sınıf oluşturmanıza gerek kalmadan ek filtreleme ve sıralama esnekliği sağlamasını istediğinizi varsayalım. Bunu başarma yollarından biri, SQL sorgusunu kabul eden bir yöntem eklemektir. Daha sonra, birleşimlere veya alt sorguya bağlı bir Where yan tümcesi gibi, denetleyicide istediğiniz herhangi bir filtre veya sıralama türünü belirtebilirsiniz. Bu bölümde böyle bir yöntemi nasıl uygulayabileceğinizi göreceksiniz.

GetWithRawSqlGenericRepository.cs dosyasına aşağıdaki kodu ekleyerek yöntemini oluşturun:

public virtual IEnumerable<TEntity> GetWithRawSql(string query, params object[] parameters)
{
    return dbSet.SqlQuery(query, parameters).ToList();
}

CourseController.cs dosyasında, aşağıdaki örnekte gösterildiği gibi yönteminden Details yeni yöntemi çağırın:

public ActionResult Details(int id)
{
    var query = "SELECT * FROM Course WHERE CourseID = @p0";
    return View(unitOfWork.CourseRepository.GetWithRawSql(query, id).Single());
}

Bu durumda yöntemini kullanmış GetByID olabilir, ancak yöntemini kullanarak yönteminin GetWithRawSqlGetWithRawSQL çalıştığını doğrulamış olursunuz.

Seçme sorgusunun çalıştığını doğrulamak için Ayrıntılar sayfasını çalıştırın (Bir kurs için Kurs sekmesini ve ardından Ayrıntılar'ı seçin).

Contoso Üniversite Ayrıntıları sayfasını gösteren ekran görüntüsü.

Diğer Nesne Türlerini Döndüren Bir Sorguyu Çağırma

Daha önce Hakkında sayfası için her kayıt tarihi için öğrenci sayısını gösteren bir öğrenci istatistikleri kılavuzu oluşturdunuz. HomeController.cs dosyasında bunu sağlayan kod LINQ kullanır:

var data = from student in db.Students
           group student by student.EnrollmentDate into dateGroup
           select new EnrollmentDateGroup()
           {
               EnrollmentDate = dateGroup.Key,
               StudentCount = dateGroup.Count()
           };

LINQ kullanmak yerine bu verileri doğrudan SQL'de alan kodu yazmak istediğinizi varsayalım. Bunu yapmak için varlık nesnelerinden başka bir şey döndüren bir sorgu çalıştırmanız gerekir; bu da yöntemini kullanmanız Database.SqlQuery gerektiği anlamına gelir.

HomeController.cs dosyasında, yöntemindeki About LINQ deyimini aşağıdaki kodla değiştirin:

var query = "SELECT EnrollmentDate, COUNT(*) AS StudentCount "
    + "FROM Person "
    + "WHERE EnrollmentDate IS NOT NULL "
    + "GROUP BY EnrollmentDate";
var data = db.Database.SqlQuery<EnrollmentDateGroup>(query);

Hakkında sayfasını çalıştırın. Daha önce görüntülediği verileri görüntüler.

Contoso University Hakkında sayfasını gösteren ekran görüntüsü.

Güncelleştirme Sorgusu Çağırma

Contoso Üniversitesi yöneticilerinin veritabanında her kursun kredi sayısını değiştirme gibi toplu değişiklikler yapabilmek istediğini varsayalım. Üniversitenin çok sayıda kursu varsa, bunların tümünü varlık olarak almak ve tek tek değiştirmek verimsiz olacaktır. Bu bölümde, kullanıcının tüm kurslar için kredi sayısını değiştirecek bir faktör belirtmesine olanak tanıyan bir web sayfası uygulayacak ve değişikliği bir SQL UPDATE deyimi yürüterek yapacaksınız. Web sayfası aşağıdaki çizim gibi görünür:

Kurs Kredilerini Güncelleştir ilk sayfasını gösteren ekran görüntüsü. Metin alanına 2 sayısı girilir.

Önceki öğreticide, denetleyicideki varlıkları okumak ve güncelleştirmek Course için genel depoyu Course kullandınız. Bu toplu güncelleştirme işlemi için, genel depoda olmayan yeni bir depo yöntemi oluşturmanız gerekir. Bunu yapmak için sınıfından türetilen GenericRepository ayrılmış CourseRepository bir sınıf oluşturacaksınız.

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

using System;
using ContosoUniversity.Models;

namespace ContosoUniversity.DAL
{
    public class CourseRepository : GenericRepository<Course>
    {
        public CourseRepository(SchoolContext context)
            : base(context)
        {
        }

        public int UpdateCourseCredits(int multiplier)
        {
            return context.Database.ExecuteSqlCommand("UPDATE Course SET Credits = Credits * {0}", multiplier);
        }

    }
}

UnitOfWork.cs dosyasında depo türünü GenericRepository<Course> olarak değiştirin CourseCourseRepository:

private CourseRepository courseRepository;
public CourseRepository CourseRepository
{
    get
    {

        if (this.courseRepository == null)
        {
            this.courseRepository = new CourseRepository(context);
        }
        return courseRepository;
    }
}

CourseController.cs dosyasına bir UpdateCourseCredits yöntem ekleyin:

public ActionResult UpdateCourseCredits(int? multiplier)
{
    if (multiplier != null)
    {
        ViewBag.RowsAffected = unitOfWork.CourseRepository.UpdateCourseCredits(multiplier.Value);
    }
    return View();
}

Bu yöntem hem hem de HttpGetHttpPostiçin kullanılır. HttpGetUpdateCourseCredits Yöntem çalıştırıldığında değişken multiplier null olur ve görünümde önceki çizimde gösterildiği gibi boş bir metin kutusu ve gönder düğmesi görüntülenir.

Güncelleştir düğmesine tıklandığında ve HttpPost yöntem çalıştırıldığında, multiplier metin kutusuna değer girilir. Kod daha sonra etkilenen satırların sayısını döndüren depo UpdateCourseCredits yöntemini çağırır ve bu değer nesnede ViewBag depolanır. Görünüm, nesnedeki etkilenen satırların sayısını aldığında, aşağıdaki çizimde ViewBag gösterildiği gibi metin kutusu ve gönder düğmesi yerine bu sayıyı görüntüler:

Etkilenen Contoso University Update Course Credits satırlarını gösteren ekran görüntüsü.

Kurs Kredilerini Güncelleştir sayfasının Views\Course klasöründe bir görünüm oluşturun:

Görünüm Ekle iletişim kutusunu gösteren ekran görüntüsü. Ders Kredilerini Güncelleştir, Görünüm adı metin alanına girilir.

Views\Course\UpdateCourseCredits.cshtml içinde şablon kodunu aşağıdaki kodla değiştirin:

@model ContosoUniversity.Models.Course

@{
    ViewBag.Title = "UpdateCourseCredits";
}

<h2>Update Course Credits</h2>

@if (ViewBag.RowsAffected == null)
{
    using (Html.BeginForm())
    {
        <p>
            Enter a number to multiply every course's credits by: @Html.TextBox("multiplier")
        </p>
        <p>
            <input type="submit" value="Update" />
        </p>
    }
}
@if (ViewBag.RowsAffected != null)
{
    <p>
        Number of rows updated: @ViewBag.RowsAffected
    </p>
}
<div>
    @Html.ActionLink("Back to List", "Index")
</div>

Kurslar sekmesini seçip tarayıcının UpdateCourseCredits adres çubuğunda url'nin sonuna "/UpdateCourseCredits" ekleyerek yöntemini çalıştırın (örneğin: http://localhost:50205/Course/UpdateCourseCredits). Metin kutusuna bir sayı girin:

Metin alanına 2 sayısının girilmiş olduğu Ders Kredilerini Güncelleştir başlangıç sayfasını gösteren ekran görüntüsü.

Güncelleştir’e tıklayın. Etkilenen satır sayısını görürsünüz:

Güncelleştirilen satır sayısını içeren Kurs Kredilerini Güncelleştir sayfasını gösteren ekran görüntüsü.

Düzeltilmiş kredi sayısına sahip kursların listesini görmek için Listeye Geri Dön'e tıklayın.

Kurs Dizini sayfasını gösteren ekran görüntüsü. Düzeltilmiş kredi sayısıyla birlikte bir ders listesi gösterilir.

Ham SQL sorguları hakkında daha fazla bilgi için Entity Framework ekip blogundaki Ham SQL Sorguları'na bakın.

sorguları No-Tracking

Veritabanı bağlamı veritabanı satırlarını aldığında ve bunları temsil eden varlık nesneleri oluşturduğunda, varsayılan olarak bellekteki varlıkların veritabanındakilerle eşitlenmiş olup olmadığını izler. Bellekteki veriler önbellek görevi görür ve bir varlığı güncelleştirdiğinizde kullanılır. Bağlam örnekleri genellikle kısa süreli olduğundan (her istek için yeni bir tane oluşturulur ve atılır) ve bir varlığı okuyan bağlam genellikle bu varlık yeniden kullanılmadan önce atıldığından, bu önbelleğe alma genellikle bir web uygulamasında gereksizdir.

yöntemini kullanarak AsNoTracking bağlamın sorgu için varlık nesnelerinin izlenip izleneceğini belirtebilirsiniz. Bunu yapmak isteyebileceğiniz tipik senaryolar şunlardır:

  • Sorgu, izlemeyi kapatmanın performansı önemli ölçüde artırabileceği kadar büyük miktarda veri alır.
  • Güncelleştirmek için bir varlık eklemek istiyorsunuz, ancak daha önce aynı varlığı farklı bir amaç için almıştınız. Varlık veritabanı bağlamı tarafından zaten izlendiğinden, değiştirmek istediğiniz varlığı ekleyemezsiniz. Bunun olmasını önlemenin bir yolu, önceki sorguda seçeneğini kullanmaktır AsNoTracking .

Bu bölümde, bu senaryoların ikincisini gösteren iş mantığını uygulayacaksınız. Özel olarak, eğitmenin birden fazla departmanın yöneticisi olmadığını belirten bir iş kuralı uygulayacaksınız.

DepartmentController.cs dosyasında, iki departmanın aynı yöneticiye sahip olmadığından emin olmak için ve Create yöntemlerinden Edit çağırabileceğiniz yeni bir yöntem ekleyin:

private void ValidateOneAdministratorAssignmentPerInstructor(Department department)
{
    if (department.PersonID != null)
    {
        var duplicateDepartment = db.Departments
            .Include("Administrator")
            .Where(d => d.PersonID == department.PersonID)
            .FirstOrDefault();
        if (duplicateDepartment != null && duplicateDepartment.DepartmentID != department.DepartmentID)
        {
            var errorMessage = String.Format(
                "Instructor {0} {1} is already administrator of the {2} department.",
                duplicateDepartment.Administrator.FirstMidName,
                duplicateDepartment.Administrator.LastName,
                duplicateDepartment.Name);
            ModelState.AddModelError(string.Empty, errorMessage);
        }
    }
}

Doğrulama hatası yoksa bu yeni yöntemi çağırmak için yönteminin HttpPostEdit bloğuna kod try ekleyin. Blok try artık aşağıdaki örneğe benzer:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(
   [Bind(Include = "DepartmentID, Name, Budget, StartDate, RowVersion, PersonID")]
    Department department)
{
   try
   {
      if (ModelState.IsValid)
      {
         ValidateOneAdministratorAssignmentPerInstructor(department);
      }

      if (ModelState.IsValid)
      {
         db.Entry(department).State = EntityState.Modified;
         db.SaveChanges();
         return RedirectToAction("Index");
      }
   }
   catch (DbUpdateConcurrencyException ex)
   {
      var entry = ex.Entries.Single();
      var clientValues = (Department)entry.Entity;

Bölüm Düzenleme sayfasını çalıştırın ve bir departmanın yöneticisini zaten farklı bir departmanın yöneticisi olan bir eğitmen olarak değiştirmeyi deneyin. Beklenen hata iletisini alırsınız:

Yinelenen yönetici hata iletisini içeren Bölüm Düzenleme sayfasını gösteren ekran görüntüsü.

Şimdi Departman Düzenleme sayfasını yeniden çalıştırın ve bu kez Bütçe tutarını değiştirin. Kaydet'e tıkladığınızda bir hata sayfası görürsünüz:

Nesne durumu yöneticisi hata iletisini içeren Bölüm Düzenleme sayfasını gösteren ekran görüntüsü.

Özel durum hata iletisi şudur: "An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key." Bu, aşağıdaki olay dizisi nedeniyle oluştu:

  • Edit yöntemi, Kim Abercrombie'yi yöneticisi olarak içeren tüm departmanları alan yöntemini çağırırValidateOneAdministratorAssignmentPerInstructor. Bu, İngilizce bölümünün okunmasının nedenidir. Bu bölüm düzenlendiği için hata bildirilir. Ancak bu okuma işleminin sonucunda, veritabanından okunan İngilizce departman varlığı artık veritabanı bağlamı tarafından izleniyor.
  • yöntemi, Edit MVC model bağlayıcısı tarafından oluşturulan İngilizce departman varlığında bayrağını ayarlamaya Modified çalışır, ancak bağlam zaten İngilizce bölümü için bir varlığı izlediğinden bu başarısız olur.

Bu sorunun bir çözümü, bağlamın doğrulama sorgusu tarafından alınan bellek içi departman varlıklarını izlemesini sağlamaktır. Bunu yapmanın dezavantajı yoktur, çünkü bu varlığı güncelleştirmeyecek veya bellekte önbelleğe alınmasından yararlanacak şekilde yeniden okumayacaksınız.

DepartmentController.cs dosyasındaki yöntemindeValidateOneAdministratorAssignmentPerInstructor, aşağıda gösterildiği gibi izleme yok belirtin:

var duplicateDepartment = db.Departments
   .Include("Administrator")
   .Where(d => d.PersonID == department.PersonID)
   .AsNoTracking()
   .FirstOrDefault();

Bir departmanın Bütçe miktarını düzenleme girişiminizi yineleyin. Bu kez işlem başarılı olur ve site, düzeltilen bütçe değerini gösteren Departmanlar Dizini sayfasına beklendiği gibi döner.

Veritabanına Gönderilen Sorguları denetleme

Bazen veritabanına gönderilen gerçek SQL sorgularını görebilmek yararlı olabilir. Bunu yapmak için hata ayıklayıcıdaki bir sorgu değişkenini inceleyebilir veya sorgunun ToString yöntemini çağırabilirsiniz. Bunu denemek için basit bir sorguya bakacak ve ardından hevesle yükleme, filtreleme ve sıralama gibi seçenekler eklerken bu sorguya ne olacağına bakacaksınız.

Controllers/CourseController'da yöntemini aşağıdaki kodla değiştirinIndex:

public ViewResult Index()
{
    var courses = unitOfWork.CourseRepository.Get();
    return View(courses.ToList());
}

Şimdi genericRepository.cs dosyasında yönteminin return query.ToList();return orderBy(query).ToList(); ve deyimlerinde Get bir kesme noktası ayarlayın. Projeyi hata ayıklama modunda çalıştırın ve Kurs Dizini sayfasını seçin. Kod kesme noktasına ulaştığında değişkenini query inceleyin. SQL Server gönderilen sorguyu görürsünüz. Basit bir Select ifadedir:

{SELECT 
[Extent1].[CourseID] AS [CourseID], 
[Extent1].[Title] AS [Title], 
[Extent1].[Credits] AS [Credits], 
[Extent1].[DepartmentID] AS [DepartmentID]
FROM [Course] AS [Extent1]}

Örnek web uygulaması Genel Depo sekmesini gösteren ekran görüntüsü. Sorgu değişkeni seçilir.

Sorgular Visual Studio'daki hata ayıklama pencerelerinde görüntülenemeyecek kadar uzun olabilir. Sorgunun tamamını görmek için değişken değerini kopyalayıp bir metin düzenleyicisine yapıştırabilirsiniz:

Değişken değeri seçildiğinde açılan menünün görüntülendiği ekran görüntüsü. Değeri Kopyala seçeneği vurgulanır.

Şimdi, kullanıcıların belirli bir departman için filtre uygulayabilmesi için Kurs Dizini sayfasına bir açılan liste ekleyeceksiniz. Kursları başlığa göre sıralar ve gezinti özelliği için Department hevesle yüklemeyi belirtirsiniz. CourseController.cs dosyasında yöntemini aşağıdaki kodla değiştirinIndex:

public ActionResult Index(int? SelectedDepartment)
{
    var departments = unitOfWork.DepartmentRepository.Get(
        orderBy: q => q.OrderBy(d => d.Name));
    ViewBag.SelectedDepartment = new SelectList(departments, "DepartmentID", "Name", SelectedDepartment);

    int departmentID = SelectedDepartment.GetValueOrDefault(); 
    return View(unitOfWork.CourseRepository.Get(
        filter: d => !SelectedDepartment.HasValue || d.DepartmentID == departmentID,
        orderBy: q => q.OrderBy(d => d.CourseID),
        includeProperties: "Department"));
}

yöntemi, parametresindeki açılan listenin SelectedDepartment seçili değerini alır. Hiçbir şey seçilmezse, bu parametre null olur.

SelectList Tüm bölümleri içeren bir koleksiyon, açılan listenin görünümüne geçirilir. Oluşturucuya SelectList geçirilen parametreler değer alanı adını, metin alanı adını ve seçili öğeyi belirtir.

Get Deponun yöntemi Course için kod bir filtre ifadesi, sıralama düzeni ve gezinti özelliği için Department hevesle yüklemeyi belirtir. Açılan listede hiçbir şey seçili değilse (yani SelectedDepartment null) filtre ifadesi her zaman döndürürtrue.

Views\Course\Index.cshtml dosyasında, açılış table etiketinden hemen önce, açılan listeyi ve gönder düğmesini oluşturmak için aşağıdaki kodu ekleyin:

@using (Html.BeginForm())
{
    <p>Select Department: @Html.DropDownList("SelectedDepartment","All")   
    <input type="submit" value="Filter" /></p>
}

Sınıfta kesme noktaları hala ayarlanmış GenericRepository durumdayken Kurs Dizini sayfasını çalıştırın. Sayfanın tarayıcıda görüntülenmesi için kodun kesme noktasına ilk iki kez isabet etmesiyle devam edin. Açılan listeden bir departman seçin ve Filtrele'ye tıklayın:

Ekonomi Bölümü'nin seçili olduğu Kurs Dizini sayfasını gösteren ekran görüntüsü.

Bu kez ilk kesme noktası, açılan listenin departmanlar sorgusu için olacaktır. Bunu atlayın ve sorgunun query şimdi nasıl Course göründüğünü görmek için kod kesme noktasına bir sonraki eriştiğinde değişkeni görüntüleyin. Aşağıdakine benzer bir şey görürsünüz:

{SELECT 
[Extent1].[CourseID] AS [CourseID], 
[Extent1].[Title] AS [Title], 
[Extent1].[Credits] AS [Credits], 
[Extent1].[DepartmentID] AS [DepartmentID], 
[Extent2].[DepartmentID] AS [DepartmentID1], 
[Extent2].[Name] AS [Name], 
[Extent2].[Budget] AS [Budget], 
[Extent2].[StartDate] AS [StartDate], 
[Extent2].[PersonID] AS [PersonID], 
[Extent2].[Timestamp] AS [Timestamp]
FROM  [Course] AS [Extent1]
INNER JOIN [Department] AS [Extent2] ON [Extent1].[DepartmentID] = [Extent2].[DepartmentID]
WHERE (@p__linq__0 IS NULL) OR ([Extent1].[DepartmentID] = @p__linq__1)}

Sorgunun artık verilerle Course birlikte veri yükleyen Department bir JOIN sorgu olduğunu ve bir WHERE yan tümcesi içerdiğini görebilirsiniz.

Ara Sunucu Sınıfları ile Çalışma

Entity Framework varlık örnekleri oluşturduğunda (örneğin, bir sorguyu yürütürken), bunları genellikle varlık için ara sunucu işlevi gören dinamik olarak oluşturulmuş türetilmiş bir türün örnekleri olarak oluşturur. Bu proxy, özelliğe erişildiğinde eylemleri otomatik olarak gerçekleştirmek için kancalar eklemek üzere varlığın bazı sanal özelliklerini geçersiz kılar. Örneğin, bu mekanizma ilişkilerin gecikmeli yüklenmesini desteklemek için kullanılır.

Çoğu zaman proxy'lerin bu kullanımından haberdar olmanız gerekmez, ancak istisnalar vardır:

  • Bazı senaryolarda Entity Framework'ün ara sunucu örnekleri oluşturmasını engellemek isteyebilirsiniz. Örneğin, ara sunucu olmayan örnekleri seri hale getirme, ara sunucu örneklerini seri hale getirmekten daha verimli olabilir.
  • işlecini kullanarak bir varlık sınıfı örneği new oluştururken ara sunucu örneği almazsınız. Bu, gecikmeli yükleme ve otomatik değişiklik izleme gibi işlevlere sahip olmadığınız anlamına gelir. Bu genellikle normaldir; veritabanında olmayan yeni bir varlık oluşturduğunuz ve varlığı açıkça olarak olarak Addedişaretliyorsanız genellikle değişiklik izlemesine gerek duymadığınız için genellikle yavaş yüklemeye ihtiyacınız yoktur. Ancak, gecikmeli yüklemeye ihtiyacınız varsa ve değişiklik izlemeye ihtiyacınız varsa, sınıfının yöntemini DbSet kullanarak Create proxy'lerle yeni varlık örnekleri oluşturabilirsiniz.
  • Bir ara sunucu türünden gerçek bir varlık türü almak isteyebilirsiniz. Bir ara sunucu türü örneğinin gerçek varlık türünü almak için sınıfının yöntemini ObjectContext kullanabilirsinizGetObjectType.

Daha fazla bilgi için Entity Framework ekip blogundaki Proxy'lerle çalışma bölümüne bakın.

Değişiklikleri Otomatik Algılamayı Devre Dışı Bırakma

Entity Framework, bir varlığın geçerli değerlerini özgün değerlerle karşılaştırarak varlığın nasıl değiştiğini (ve bu nedenle veritabanına hangi güncelleştirmelerin gönderilmesi gerektiğini) belirler. Özgün değerler, varlık sorgulandığında veya eklendiğinde depolanır. Otomatik değişiklik algılamaya neden olan yöntemlerden bazıları şunlardır:

  • DbSet.Find
  • DbSet.Local
  • DbSet.Remove
  • DbSet.Add
  • DbSet.Attach
  • DbContext.SaveChanges
  • DbContext.GetValidationErrors
  • DbContext.Entry
  • DbChangeTracker.Entries

Çok sayıda varlığı izliyorsanız ve bu yöntemlerden birini döngü içinde birçok kez çağırıyorsanız, AutoDetectChangesEnabled özelliğini kullanarak otomatik değişiklik algılamayı geçici olarak kapatarak önemli performans iyileştirmeleri alabilirsiniz. Daha fazla bilgi için bkz. Değişiklikleri Otomatik Olarak Algılama.

Değişiklikleri Kaydederken Doğrulamayı Devre Dışı Bırakma

yöntemini çağırdığınızda SaveChanges , Entity Framework varsayılan olarak veritabanını güncelleştirmeden önce değiştirilen tüm varlıkların tüm özelliklerindeki verileri doğrular. Çok sayıda varlığı güncelleştirdiyseniz ve verileri zaten doğrulamışsanız, bu iş gereksizdir ve doğrulamayı geçici olarak kapatarak değişiklikleri kaydetme işleminin daha kısa sürmesini sağlayabilirsiniz. ValidateOnSaveEnabled özelliğini kullanarak bunu yapabilirsiniz. Daha fazla bilgi için bkz . Doğrulama.

Özet

Bu işlem, Entity Framework'ün bir ASP.NET MVC uygulamasında kullanılmasıyla ilgili bu öğretici dizisini tamamlar. Diğer Entity Framework kaynaklarına bağlantılar ASP.NET Veri Erişimi İçerik Eşlemesi'nde bulunabilir.

Web uygulamanızı derledikten sonra dağıtma hakkında daha fazla bilgi için bkz. MSDN Kitaplığı'nda Dağıtım İçerik Haritası ASP.NET .

Kimlik doğrulaması ve yetkilendirme gibi MVC ile ilgili diğer konular hakkında bilgi için bkz. MVC Önerilen Kaynaklar.

Teşekkürler

  • Tom Dykstra bu öğreticinin özgün sürümünü yazdı ve Microsoft Web Platformu ve Araçları İçerik Ekibi'nin kıdemli programlama yazarıdır.
  • Rick Anderson (twitter @RickAndMSFT) bu öğreticiyi birlikte yazdı ve çalışmaların çoğunu EF 5 ve MVC 4 için güncelleştirdi. Rick, Microsoft'un Azure ve MVC'ye odaklanan kıdemli bir programlama yazarıdır.
  • Rowan Miller ve Entity Framework ekibinin diğer üyeleri, kod incelemelerine yardımcı oldu ve EF 5 öğreticisini güncelleştirirken ortaya gelen geçişlerle ilgili birçok sorunun hatalarını ayıklamaya yardımcı oldu.

VB

Öğretici başlangıçta üretildiğinde tamamlanan indirme projesinin hem C# hem de VB sürümlerini sağladık. Bu güncelleştirme ile serinin herhangi bir yerinde çalışmaya başlamayı kolaylaştırmak amacıyla her bölüm için bir C# indirilebilir projesi sağlıyoruz, ancak zaman sınırlamaları ve diğer önceliklerden dolayı VB için bunu gerçekleştirmedik. Bu öğreticileri kullanarak bir VB projesi oluşturuyorsanız ve bunu başkalarıyla paylaşmak isterseniz lütfen bize bildirin.

Hatalar ve Geçici Çözümler

Gölge kopya oluşturulamıyor/gölge kopya oluşturulamıyor

Hata İletisi:

Bu dosya zaten mevcut olduğunda 'DotNetOpenAuth.OpenId' gölge kopyası oluşturulamıyor...

Çözüm:

Birkaç saniye bekleyin ve sayfayı yenileyin.

Update-Database tanınmıyor

Hata İletisi:

'Update-Database' terimi bir cmdlet, işlev, betik dosyası veya çalıştırılabilir programın adı olarak tanınmaz. Adın yazımını denetleyin veya yol eklenmişse, yolun doğru olduğunu doğrulayın ve yeniden deneyin.(PMC'deki komuttan Update-Database .)

Çözüm:

Visual Studio'dan çıkın. Projeyi yeniden açın ve yeniden deneyin.

Doğrulama başarısız oldu

Hata İletisi:

Bir veya daha fazla varlık için doğrulama başarısız oldu. Daha fazla ayrıntı için bkz. 'EntityValidationErrors' özelliği. (PMC'deki komuttan Update-Database .)

Çözüm:

Bu sorunun nedenlerinden biri, yöntem çalıştırıldığında karşılaşılan Seed doğrulama hatalarıdır. Yöntemin hatalarını ayıklamayla ilgili ipuçları için bkz. Varlık Çerçevesi (EF) DB'lerini Ayıklama ve Hatalarını Ayıklama Seed .

HTTP 500.19 hatası

Hata İletisi:

HTTP Hatası 500.19 - İç Sunucu Hatası
sayfayla ilgili yapılandırma verileri geçersiz olduğundan istenen sayfaya erişilemiyor.

Çözüm:

Bu hatayı alma yollarından biri, çözümün her biri aynı bağlantı noktası numarasını kullanan birden çok kopyasına sahip olmaktır. Bu sorunu genellikle Visual Studio'nun tüm örneklerinden çıkıp üzerinde çalıştığınız projeyi yeniden başlatarak çözebilirsiniz. Bu işe yaramazsa bağlantı noktası numarasını değiştirmeyi deneyin. Proje dosyasına sağ tıklayın ve ardından özellikler'e tıklayın. Web sekmesini seçin ve Proje Url'si metin kutusundaki bağlantı noktası numarasını değiştirin.

SQL Server örneği bulma hatası

Hata İletisi:

SQL Server ile bağlantı kurulmaya çalışılırken ağ ile ilişkili veya örneğe özgü bir hata oluştu. Sunucu bulunamadı veya erişilebilir değildi. Örnek adının doğru olduğundan ve SQL Server'ın uzak bağlantılara izin verecek şekilde yapılandırıldığından emin olun. (sağlayıcı: SQL Ağ Arabirimleri, hata: 26 - Belirtilen Sunucuyu/Örneği Bulma Hatası)

Çözüm:

Bağlantı dizesini denetleyin. Veritabanını el ile sildiyseniz, yapı dizesindeki veritabanının adını değiştirin.