Veri Erişim Katmanını Oluşturma

tarafından Erik Reitan

Bu öğretici serisi, web için ASP.NET 4.5 ve Microsoft Visual Studio Express 2013 kullanarak ASP.NET Web Forms uygulaması oluşturmanın temellerini öğretecektir. Bu öğretici serisine eşlik etmek için C# kaynak koduna sahip bir Visual Studio 2013 projesi kullanılabilir.

Bu öğreticide, ASP.NET Web Forms ve Entity Framework Code First kullanarak veritabanından veri oluşturma, bunlara erişme ve verileri gözden geçirme işlemleri açıklanmaktadır. Bu öğretici, önceki "Projeyi Oluşturma" öğreticisini temel alır ve Wingtip Oyuncak Mağazası öğretici serisinin bir parçasıdır. Bu öğreticiyi tamamladığınızda, projenin Models klasöründe bulunan bir grup veri erişim sınıfı oluşturdunuz.

Öğrenecekleriniz:

  • Veri modellerini oluşturma.
  • Veritabanını başlatma ve dağıtma.
  • Uygulamayı veritabanını destekleyecek şekilde güncelleştirme ve yapılandırma.

Öğreticide sunulan özellikler şunlardır:

  • Entity Framework Code First
  • Yerel veritabanı
  • Veri Açıklamaları

Veri Modellerini Oluşturma

Entity Framework , nesne-ilişkisel eşleme (ORM) çerçevesidir. İlişkisel verilerle nesne olarak çalışmanıza olanak tanır ve genellikle yazmanız gereken veri erişim kodunun çoğunu ortadan kaldırır. Entity Framework kullanarak LINQ kullanarak sorgular verebilir, ardından verileri kesin olarak yazılan nesneler olarak alıp işleyebilirsiniz. LINQ, verileri sorgulamaya ve güncelleştirmeye yönelik desenler sağlar. Entity Framework'ün kullanılması, veri erişimiyle ilgili temel bilgilere odaklanmak yerine uygulamanızın geri kalanını oluşturmaya odaklanmanızı sağlar. Bu öğretici serisinin ilerleyen bölümlerinde, gezinti ve ürün sorgularını doldurmak için verilerin nasıl kullanılacağını göstereceğiz.

Entity Framework , Code First adlı bir geliştirme paradigması destekler. Code First, sınıflar kullanarak veri modellerinizi tanımlamanızı sağlar. Sınıf, diğer tür, yöntem ve olay değişkenlerini gruplandırarak kendi özel türlerinizi oluşturmanıza olanak tanıyan bir yapıdır. Sınıfları mevcut bir veritabanına eşleyebilir veya veritabanı oluşturmak için kullanabilirsiniz. Bu öğreticide, veri modeli sınıfları yazarak veri modellerini oluşturacaksınız. Ardından Entity Framework'ün veritabanını bu yeni sınıflardan anında oluşturmasına izin vereceksiniz.

İlk olarak, Web Forms uygulamasının veri modellerini tanımlayan varlık sınıflarını oluşturacaksınız. Ardından varlık sınıflarını yöneten ve veritabanına veri erişimi sağlayan bir bağlam sınıfı oluşturacaksınız. Veritabanını doldurmak için kullanacağınız bir başlatıcı sınıfı da oluşturacaksınız.

Entity Framework ve Başvurular

Varsayılan olarak, Web Forms şablonunu kullanarak yeni bir ASP.NET Web Uygulaması oluşturduğunuzda Entity Framework eklenir. Entity Framework bir NuGet paketi olarak yüklenebilir, kaldırılabilir ve güncelleştirilebilir.

Bu NuGet paketi projenizde aşağıdaki çalışma zamanı derlemelerini içerir:

  • EntityFramework.dll – Entity Framework tarafından kullanılan tüm ortak çalışma zamanı kodu
  • EntityFramework.SqlServer.dll – Entity Framework için Microsoft SQL Server sağlayıcısı

Varlık Sınıfları

Verilerin şemasını tanımlamak için oluşturduğunuz sınıflara varlık sınıfları adı verilir. Veritabanı tasarımında yeniyseniz varlık sınıflarını bir veritabanının tablo tanımları olarak düşünün. sınıfındaki her özellik, veritabanının tablosunda bir sütun belirtir. Bu sınıflar, nesne odaklı kod ile veritabanının ilişkisel tablo yapısı arasında basit, nesne ilişkisel bir arabirim sağlar.

Bu öğreticide, ürünler ve kategoriler için şemaları temsil eden basit varlık sınıfları ekleyerek başlayacaksınız. Products sınıfı, her ürün için tanımlar içerir. Ürün sınıfının üyelerinin her birinin adı , , ProductName, Description, UnitPriceImagePath, CategoryID, ve CategoryolacaktırProductID. Kategori sınıfı, bir ürünün ait olabileceği her kategori için Araba, Tekne veya Uçak gibi tanımlar içerir. Kategori sınıfının üyelerinin her birinin adı , CategoryName, Descriptionve ProductsolurCategoryID. Her ürün kategorilerden birine ait olacaktır. Bu varlık sınıfları projenin mevcut Models klasörüne eklenir.

  1. Çözüm Gezgini'daModeller klasörüne sağ tıklayın ve ekle ->Yeni Öğe'yi seçin.

    Modeller klasörünün vurgulandığı ve Ekle ve Yeni Öğe açılan menülerinin seçili olduğu Çözüm Gezgini penceresinin ekran görüntüsü.

    Yeni Öğe Ekle iletişim kutusu görüntülenir.

  2. Soldaki Yüklü bölmesindeki Visual C# altında Kod'u seçin.

    Sol tarafta Visual C# açık ve Kod'un seçili olduğu Yüklü bölmesini gösteren Yeni Öğe Ekle penceresinin ekran görüntüsü.

  3. Orta bölmeden Sınıf'ı seçin ve bu yeni sınıfı Product.cs olarak adlandırın.

  4. Ekle'ye tıklayın.
    Yeni sınıf dosyası düzenleyicide görüntülenir.

  5. Varsayılan kodu aşağıdaki kodla değiştirin:

    using System.ComponentModel.DataAnnotations;
    
    namespace WingtipToys.Models
    {
        public class Product
        {
            [ScaffoldColumn(false)]
            public int ProductID { get; set; }
    
            [Required, StringLength(100), Display(Name = "Name")]
            public string ProductName { get; set; }
    
            [Required, StringLength(10000), Display(Name = "Product Description"), DataType(DataType.MultilineText)]
            public string Description { get; set; }
    
            public string ImagePath { get; set; }
    
            [Display(Name = "Price")]
            public double? UnitPrice { get; set; }
    
            public int? CategoryID { get; set; }
    
            public virtual Category Category { get; set; }
        }
    }
    
  6. 1 ile 4 arasındaki adımları yineleyerek başka bir sınıf oluşturun, ancak yeni sınıfı Category.cs olarak adlandırın ve varsayılan kodu aşağıdaki kodla değiştirin:

    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    
    namespace WingtipToys.Models
    {
        public class Category
        {
            [ScaffoldColumn(false)]
            public int CategoryID { get; set; }
    
            [Required, StringLength(100), Display(Name = "Name")]
            public string CategoryName { get; set; }
    
            [Display(Name = "Product Description")]
            public string Description { get; set; }
    
            public virtual ICollection<Product> Products { get; set; }
        }
    }
    

Daha önce belirtildiği gibi sınıfı, Category uygulamanın satmak üzere tasarlandığı ürün türünü (örneğin, "Arabalar", "Tekneler", "Roketler" vb.) temsil eder ve Product sınıf veritabanındaki tek tek ürünleri (oyuncakları) temsil eder. Bir Product nesnenin her örneği ilişkisel veritabanı tablosundaki bir satıra karşılık gelir ve Product sınıfının her özelliği ilişkisel veritabanı tablosundaki bir sütuna eşlenir. Bu öğreticinin ilerleyen bölümlerinde veritabanında bulunan ürün verilerini gözden geçireceksiniz.

Veri Açıklamaları

Sınıfların belirli üyelerinin üyeyle ilgili ayrıntıları belirten öznitelikleri olduğunu fark etmiş olabilirsiniz, örneğin [ScaffoldColumn(false)]. Bunlar veri ek açıklamalarıdır. Veri ek açıklaması öznitelikleri, bu üye için kullanıcı girişinin nasıl doğrulandığını, bunun biçimlendirmesini belirtmeyi ve veritabanı oluşturulduğunda nasıl modelleneceğini belirtmeyi açıklayabilir.

Bağlam Sınıfı

Veri erişimi için sınıfları kullanmaya başlamak için bir bağlam sınıfı tanımlamanız gerekir. Daha önce belirtildiği gibi bağlam sınıfı varlık sınıflarını (sınıf ve Category sınıf gibiProduct) yönetir ve veritabanına veri erişimi sağlar.

Bu yordam Models klasörüne yeni bir C# bağlam sınıfı ekler.

  1. Modeller klasörüne sağ tıklayın ve ekle ->Yeni Öğe'yi seçin.
    Yeni Öğe Ekle iletişim kutusu görüntülenir.

  2. Orta bölmeden Sınıf'ı seçin, bunu ProductContext.cs olarak adlandırın ve Ekle'ye tıklayın.

  3. sınıfında yer alan varsayılan kodu aşağıdaki kodla değiştirin:

    using System.Data.Entity;
    namespace WingtipToys.Models
    {
        public class ProductContext : DbContext
        {
            public ProductContext() : base("WingtipToys")
            {
            }
            public DbSet<Category> Categories { get; set; }
            public DbSet<Product> Products { get; set; }
        }
    }
    

Bu kod, kesin olarak yazılan nesnelerle çalışarak verileri sorgulama, ekleme, güncelleştirme ve silme özelliğini içeren Entity Framework'ün tüm temel işlevlerine erişebilmeniz için ad alanını ekler System.Data.Entity .

ProductContext sınıfı, veritabanındaki sınıf örneklerini getirme, depolama ve güncelleştirme Product işlemlerini gerçekleştiren Entity Framework ürün veritabanı bağlamını temsil eder. sınıfı, ProductContext Entity Framework tarafından sağlanan temel sınıftan DbContext türetilir.

Initializer Sınıfı

Bağlam ilk kez kullanıldığında veritabanını başlatmak için bazı özel mantık çalıştırmanız gerekir. Bu, ürünleri ve kategorileri hemen görüntüleyebilmeniz için veritabanına tohum verilerinin eklenmesini sağlar.

Bu yordam Models klasörüne yeni bir C# başlatıcı sınıfı ekler.

  1. Models klasöründe başka bir tane Class oluşturun ve ProductDatabaseInitializer.cs olarak adlandırın.

  2. sınıfında yer alan varsayılan kodu aşağıdaki kodla değiştirin:

    using System.Collections.Generic;
    using System.Data.Entity;
    
    namespace WingtipToys.Models
    {
      public class ProductDatabaseInitializer : DropCreateDatabaseIfModelChanges<ProductContext>
      {
        protected override void Seed(ProductContext context)
        {
          GetCategories().ForEach(c => context.Categories.Add(c));
          GetProducts().ForEach(p => context.Products.Add(p));
        }
    
        private static List<Category> GetCategories()
        {
          var categories = new List<Category> {
                    new Category
                    {
                        CategoryID = 1,
                        CategoryName = "Cars"
                    },
                    new Category
                    {
                        CategoryID = 2,
                        CategoryName = "Planes"
                    },
                    new Category
                    {
                        CategoryID = 3,
                        CategoryName = "Trucks"
                    },
                    new Category
                    {
                        CategoryID = 4,
                        CategoryName = "Boats"
                    },
                    new Category
                    {
                        CategoryID = 5,
                        CategoryName = "Rockets"
                    },
                };
    
          return categories;
        }
    
        private static List<Product> GetProducts()
        {
          var products = new List<Product> {
                    new Product
                    {
                        ProductID = 1,
                        ProductName = "Convertible Car",
                        Description = "This convertible car is fast! The engine is powered by a neutrino based battery (not included)." + 
                                      "Power it up and let it go!", 
                        ImagePath="carconvert.png",
                        UnitPrice = 22.50,
                        CategoryID = 1
                   },
                    new Product 
                    {
                        ProductID = 2,
                        ProductName = "Old-time Car",
                        Description = "There's nothing old about this toy car, except it's looks. Compatible with other old toy cars.",
                        ImagePath="carearly.png",
                        UnitPrice = 15.95,
                         CategoryID = 1
                   },
                    new Product
                    {
                        ProductID = 3,
                        ProductName = "Fast Car",
                        Description = "Yes this car is fast, but it also floats in water.",
                        ImagePath="carfast.png",
                        UnitPrice = 32.99,
                        CategoryID = 1
                    },
                    new Product
                    {
                        ProductID = 4,
                        ProductName = "Super Fast Car",
                        Description = "Use this super fast car to entertain guests. Lights and doors work!",
                        ImagePath="carfaster.png",
                        UnitPrice = 8.95,
                        CategoryID = 1
                    },
                    new Product
                    {
                        ProductID = 5,
                        ProductName = "Old Style Racer",
                        Description = "This old style racer can fly (with user assistance). Gravity controls flight duration." + 
                                      "No batteries required.",
                        ImagePath="carracer.png",
                        UnitPrice = 34.95,
                        CategoryID = 1
                    },
                    new Product
                    {
                        ProductID = 6,
                        ProductName = "Ace Plane",
                        Description = "Authentic airplane toy. Features realistic color and details.",
                        ImagePath="planeace.png",
                        UnitPrice = 95.00,
                        CategoryID = 2
                    },
                    new Product
                    {
                        ProductID = 7,
                        ProductName = "Glider",
                        Description = "This fun glider is made from real balsa wood. Some assembly required.",
                        ImagePath="planeglider.png",
                        UnitPrice = 4.95,
                        CategoryID = 2
                    },
                    new Product
                    {
                        ProductID = 8,
                        ProductName = "Paper Plane",
                        Description = "This paper plane is like no other paper plane. Some folding required.",
                        ImagePath="planepaper.png",
                        UnitPrice = 2.95,
                        CategoryID = 2
                    },
                    new Product
                    {
                        ProductID = 9,
                        ProductName = "Propeller Plane",
                        Description = "Rubber band powered plane features two wheels.",
                        ImagePath="planeprop.png",
                        UnitPrice = 32.95,
                        CategoryID = 2
                    },
                    new Product
                    {
                        ProductID = 10,
                        ProductName = "Early Truck",
                        Description = "This toy truck has a real gas powered engine. Requires regular tune ups.",
                        ImagePath="truckearly.png",
                        UnitPrice = 15.00,
                        CategoryID = 3
                    },
                    new Product
                    {
                        ProductID = 11,
                        ProductName = "Fire Truck",
                        Description = "You will have endless fun with this one quarter sized fire truck.",
                        ImagePath="truckfire.png",
                        UnitPrice = 26.00,
                        CategoryID = 3
                    },
                    new Product
                    {
                        ProductID = 12,
                        ProductName = "Big Truck",
                        Description = "This fun toy truck can be used to tow other trucks that are not as big.",
                        ImagePath="truckbig.png",
                        UnitPrice = 29.00,
                        CategoryID = 3
                    },
                    new Product
                    {
                        ProductID = 13,
                        ProductName = "Big Ship",
                        Description = "Is it a boat or a ship. Let this floating vehicle decide by using its " + 
                                      "artifically intelligent computer brain!",
                        ImagePath="boatbig.png",
                        UnitPrice = 95.00,
                        CategoryID = 4
                    },
                    new Product
                    {
                        ProductID = 14,
                        ProductName = "Paper Boat",
                        Description = "Floating fun for all! This toy boat can be assembled in seconds. Floats for minutes!" + 
                                      "Some folding required.",
                        ImagePath="boatpaper.png",
                        UnitPrice = 4.95,
                        CategoryID = 4
                    },
                    new Product
                    {
                        ProductID = 15,
                        ProductName = "Sail Boat",
                        Description = "Put this fun toy sail boat in the water and let it go!",
                        ImagePath="boatsail.png",
                        UnitPrice = 42.95,
                        CategoryID = 4
                    },
                    new Product
                    {
                        ProductID = 16,
                        ProductName = "Rocket",
                        Description = "This fun rocket will travel up to a height of 200 feet.",
                        ImagePath="rocket.png",
                        UnitPrice = 122.95,
                        CategoryID = 5
                    }
                };
    
          return products;
        }
      }
    }
    

Yukarıdaki koddan görebileceğiniz gibi, veritabanı oluşturulduğunda ve başlatıldığında özellik Seed geçersiz kılınıp ayarlanır. Seed özellik ayarlandığında, kategori ve ürünlerdeki değerler veritabanını doldurmak için kullanılır. Veritabanı oluşturulduktan sonra yukarıdaki kodu değiştirerek tohum verilerini güncelleştirmeye çalışırsanız, Web uygulamasını çalıştırdığınızda hiçbir güncelleştirme görmezsiniz. Bunun nedeni, yukarıdaki kodun çekirdek verileri sıfırlamadan önce modelin DropCreateDatabaseIfModelChanges (şema) değişip değişmediğini tanımak için sınıfının bir uygulamasını kullanmasıdır. ve Product varlık sınıflarına hiçbir değişiklik yapılmazsa Category veritabanı, tohum verileriyle yeniden başlatılmaz.

Not

Uygulamayı her çalıştırdığınızda veritabanının yeniden oluşturulmasını istiyorsanız, sınıfı yerine sınıfını DropCreateDatabaseIfModelChanges kullanabilirsinizDropCreateDatabaseAlways. Ancak bu öğretici serisi için sınıfını DropCreateDatabaseIfModelChanges kullanın.

Bu öğreticinin bu noktasında, dört yeni sınıfa ve bir varsayılan sınıfa sahip bir Models klasörünüz olacak:

Veri Erişim Katmanı Oluşturma - Modeller Klasörü

Uygulamayı Veri Modelini Kullanacak Şekilde Yapılandırma

Verileri temsil eden sınıfları oluşturduğunuza göre, uygulamayı sınıfları kullanacak şekilde yapılandırmanız gerekir. Global.asax dosyasında, modeli başlatan kodu eklersiniz. Web.config dosyasında, uygulamaya yeni veri sınıfları tarafından temsil edilen verileri depolamak için hangi veritabanını kullanacağınızı bildiren bilgiler eklersiniz. Global.asax dosyası, uygulama olaylarını veya yöntemlerini işlemek için kullanılabilir. Web.config dosyası, ASP.NET web uygulamanızın yapılandırmasını denetlemenize olanak tanır.

Global.asax dosyasını güncelleştirme

Uygulama başlatıldığında veri modellerini başlatmak için Global.asax.cs dosyasındaki işleyiciyi güncelleştireceksinizApplication_Start.

Not

Çözüm Gezgini global.asax dosyasını veya Global.asax.cs dosyasını seçerek Global.asax.cs dosyasını düzenleyebilirsiniz.

  1. Global.asax.cs dosyasındaki yöntemine Application_Start sarıyla vurgulanan aşağıdaki kodu ekleyin.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Optimization;
    using System.Web.Routing;
    using System.Web.Security;
    using System.Web.SessionState;
    using System.Data.Entity;
    using WingtipToys.Models;
    
    namespace WingtipToys
    {
        public class Global : HttpApplication
        {
            void Application_Start(object sender, EventArgs e)
            {
                // Code that runs on application startup
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                BundleConfig.RegisterBundles(BundleTable.Bundles);
    
                // Initialize the product database.
                Database.SetInitializer(new ProductDatabaseInitializer());
            }
        }
    }
    

Not

Bu öğretici serisini tarayıcıda görüntülerken sarı renkle vurgulanan kodu görüntülemek için tarayıcınızın HTML5'i desteklemesi gerekir.

Yukarıdaki kodda gösterildiği gibi, uygulama başlatıldığında, uygulama verilere ilk kez erişildiğinde çalıştırılacak başlatıcıyı belirtir. Nesneye ve nesneye erişmek Database için ek iki ad alanı ProductDatabaseInitializer gerekir.

Web.Config Dosyasını Değiştirme

Entity Framework Code First, veritabanı tohum verileriyle doldurulduğunda varsayılan konumda sizin için bir veritabanı oluştursa da, uygulamanıza kendi bağlantı bilgilerinizi eklemek veritabanı konumunu denetlemenizi sağlar. Bu veritabanı bağlantısını, projenin kökündeki uygulamanın Web.config dosyasında bir bağlantı dizesi kullanarak belirtirsiniz. Yeni bir bağlantı dizesi ekleyerek, varsayılan konumu yerine uygulamanın veri dizininde (App_Data) oluşturulacak veritabanının konumunu (wingtiptoys.mdf) yönlendirebilirsiniz. Bu değişikliği yapmak, bu öğreticinin devamında veritabanı dosyasını bulmanıza ve incelemenize olanak sağlar.

  1. Çözüm Gezgini'daWeb.config dosyasını bulun ve açın.

  2. Sarı <connectionStrings> renkle vurgulanan bağlantı dizesini Web.config dosyasının bölümüne aşağıdaki gibi ekleyin:

    <connectionStrings>
    <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-WingtipToys-20131119102907.mdf;Initial Catalog=aspnet-WingtipToys-20131119102907;Integrated Security=True"
    providerName="System.Data.SqlClient" />
    <add name="WingtipToys"
    connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\wingtiptoys.mdf;Integrated Security=True"
    providerName="System.Data.SqlClient" />
    </connectionStrings>
    

Uygulama ilk kez çalıştırıldığında, veritabanını bağlantı dizesi tarafından belirtilen konumda oluşturur. Ancak uygulamayı çalıştırmadan önce derleyelim.

Uygulama Oluşturma

Web uygulamanızdaki tüm sınıfların ve değişikliklerin işe yaradığından emin olmak için uygulamayı oluşturmanız gerekir.

  1. Hata Ayıklamenüsünden WingtipToys Oluştur'a tıklayın.
    Çıkış penceresi görüntülenir ve her şey yolunda giderse başarılı bir ileti görürsünüz.

    Veri Erişim Katmanı Oluşturma - Çıkış Pencereleri

Bir hatayla karşılaşırsanız yukarıdaki adımları yeniden denetleyin. Çıkış penceresindeki bilgiler, hangi dosyanın sorunu olduğunu ve dosyanın neresinde bir değişiklik gerektiğini gösterir. Bu bilgiler, projenizde yukarıdaki adımların hangi bölümünün gözden geçirilmesi ve düzeltilmesi gerektiğini belirlemenizi sağlar.

Özet

Serinin bu öğreticisinde, veri modelini oluşturduğunuz gibi, veritabanını başlatmak ve görmek için kullanılacak kodu da eklediniz. Ayrıca uygulamayı, uygulama çalıştırıldığında veri modellerini kullanacak şekilde yapılandırmış olmanız gerekir.

Sonraki öğreticide kullanıcı arabirimini güncelleştirip gezinti ekleyecek ve veritabanından veri alacağız. Bu, veritabanının bu öğreticide oluşturduğunuz varlık sınıflarına göre otomatik olarak oluşturulmasına neden olur.

Ek Kaynaklar

Entity Framework’e Genel Bakış
ADO.NET Entity Framework Başlangıç Kılavuzu
Entity Framework Code firstRelationships Fluent API ile Code First Development
Code First Data Annotations
Entity Framework için Üretkenlik Geliştirmeleri