Entity Framework - İlk Örnek
Sınıfları kullanarak çok basit bir model tanımlayalım. Bunları sadece Program.cs dosyasında tanımlıyoruz, ancak gerçek dünya uygulamasında sınıflarınızı ayrı dosyalara ve potansiyel olarak ayrı bir projeye ayıracaksınız. Aşağıda Code First yaklaşımını kullanarak oluşturacağımız bir veri modeli bulunmaktadır.
Model Oluştur
Öğrenci sınıfı için aşağıdaki kodu kullanarak Program.cs dosyasına aşağıdaki üç sınıfı ekleyin.
public class Student {
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
public DateTime EnrollmentDate { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
ID özelliği, bu sınıfa karşılık gelen veritabanı tablosunun birincil anahtar sütunu olacaktır.
Kayıtlar özelliği bir gezinme özelliğidir. Gezinme özellikleri, bu varlıkla ilgili diğer varlıkları tutar.
Bu durumda, Öğrenci varlığının Enrollments özelliği, söz konusu Öğrenci varlığıyla ilişkili tüm Enrollment varlıklarını tutacaktır.
Gezinme özellikleri genellikle, geç yükleme gibi belirli Entity Framework işlevlerinden yararlanabilmeleri için sanal olarak tanımlanır.
Bir gezinme özelliği birden çok varlığı tutabiliyorsa (çoktan çoğa veya bire çok ilişkilerinde olduğu gibi), türünün ICollection gibi girişlerin eklenebileceği, silinebileceği ve güncellenebileceği bir liste olması gerekir.
Kurs sınıfı için uygulama aşağıdadır.
public class Course {
public int CourseID { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
Enrollments özelliği, bir gezinme özelliğidir. Bir Kurs varlığı, herhangi bir sayıda Enrollment varlığıyla ilişkilendirilebilir.
Kayıt sınıfı ve numaralandırma için uygulama aşağıdadır.
public enum Grade {
A, B, C, D, F
}
public class Enrollment {
public int EnrollmentID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; }
public Grade? Grade { get; set; }
public virtual Course Course { get; set; }
public virtual Student Student { get; set; }
}
EnrollmentID özelliği birincil anahtar olacaktır.
Grade özelliği bir numaralandırmadır. Grade türü bildiriminden sonraki soru işareti, Grade özelliğinin null yapılabilir olduğunu gösterir.
Boş olan bir not, sıfır nottan farklıdır. Null, notun bilinmediği veya henüz atanmadığı anlamına gelir.
StudentID ve CourseID özellikleri yabancı anahtarlardır ve ilgili gezinme özellikleri Student ve Course'tur.
Bir Kayıt varlığı, bir Öğrenci ve bir Kurs varlığıyla ilişkilendirilir, bu nedenle mülk yalnızca tek bir Öğrenci ve Kurs varlığını tutabilir.
Veritabanı Bağlamı Oluşturun
Belirli bir veri modeli için Entity Framework işlevselliğini koordine eden ana sınıf, verileri sorgulamaya ve kaydetmeye izin veren veritabanı bağlam sınıfıdır. Bu sınıfı, DbContext sınıfından türeterek ve yazılan bir DbSet göstererek oluşturabilirsiniz.
public class MyContext : DbContext {
public virtual DbSet<Course> Courses { get; set; }
public virtual DbSet<Enrollment> Enrollments { get; set; }
public virtual DbSet<Student> Students { get; set; }
}
Program.cs dosyasındaki kodun tamamı aşağıdadır.
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EFCodeFirstDemo {
class Program {
static void Main(string[] args) {}
}
public enum Grade {
A, B, C, D, F
}
public class Enrollment {
public int EnrollmentID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; }
public Grade? Grade { get; set; }
public virtual Course Course { get; set; }
public virtual Student Student { get; set; }
}
public class Student {
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
public DateTime EnrollmentDate { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
public class Course {
public int CourseID { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
public class MyContext : DbContext {
public virtual DbSet<Course> Courses { get; set; }
public virtual DbSet<Enrollment> Enrollments { get; set; }
public virtual DbSet<Student> Students { get; set; }
}
}
Yukarıdaki kod, verileri depolamaya ve almaya başlamamız için tek ihtiyacımız olan şeydir. Biraz veri ekleyip sonra geri alalım. Ana yöntemdeki kod aşağıdadır.
static void Main(string[] args) {
using (var context = new MyContext()) {
// Create and save a new Students
Console.WriteLine("Adding new students");
var student = new Student {
FirstMidName = "Alain", LastName = "Bomer",
EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
};
context.Students.Add(student);
var student1 = new Student {
FirstMidName = "Mark", LastName = "Upston",
EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())
};
context.Students.Add(student1);
context.SaveChanges();
// Display all Students from the database
var students = (from s in context.Students
orderby s.FirstMidName select s).ToList<Student>();
Console.WriteLine("Retrieve all Students from the database:");
foreach (var stdnt in students) {
string name = stdnt.FirstMidName + " " + stdnt.LastName;
Console.WriteLine("ID: {0}, Name: {1}", stdnt.ID, name);
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
Yukarıdaki kod çalıştırıldığında, aşağıdaki çıktıyı alacaksınız.
Adding new students
Retrieve all Students from the database:
ID: 1, Name: Alain Bomer
ID: 2, Name: Mark Upston
Press any key to exit...
Şimdi akla gelen soru, veri ve bazı verileri eklediğimiz veri tabanının nerede olduğu ve sonra veri tabanından geri aldığımızdır. Geleneksel olarak, DbContext sizin için bir veritabanı oluşturmuştur.
Yerel bir SQL Express örneği mevcutsa, Code First bu örnekte veritabanını oluşturmuştur.
SQL Express kullanılamıyorsa, Code First LocalDb'yi deneyecek ve kullanacaktır.
Veritabanı, türetilmiş bağlamın tam nitelikli adından sonra adlandırılır.
Bizim durumumuzda, SQL Express örneği mevcuttur ve aşağıdaki görüntüde gösterildiği gibi veritabanı adı EFCodeFirstDemo.MyContext'dir.
Bunlar yalnızca varsayılan kurallardır ve Code First'ün kullandığı veritabanını değiştirmenin çeşitli yolları vardır.
Yukarıdaki görüntüde de görebileceğiniz gibi, Öğrenci, Kurslar ve Kayıtlar tablolarını oluşturmuştur ve her tablo uygun veri türü ve uzunlukta sütunlar içermektedir.
Sütun adları ve veri türü, ilgili alan sınıflarının özellikleriyle de eşleşir.
Veritabanı Başlatma
Yukarıdaki örnekte Code First'ün otomatik olarak bir veritabanı oluşturduğunu gördük, ancak veritabanı ve sunucunun adını değiştirmek isterseniz Code First'ün bir veritabanını başlatırken veritabanı adını ve sunucuyu nasıl belirlediğini görelim. Aşağıdaki şemaya bir göz atın.
Bağlam sınıfının temel yapıcısını aşağıdaki şekillerde tanımlayabilirsiniz.
- Parametre Yok
- Veri tabanı ismi
- Bağlantı Dizesi Adı
Parametre Yok
Yukarıdaki örnekte gösterildiği gibi herhangi bir parametre olmadan bağlam sınıfının temel yapıcısını belirtirseniz, varlık çerçevesi yerel SQLEXPRESS sunucunuzda {Namespace} adıyla bir veritabanı oluşturur. {Bağlam sınıfı adı}.
Yukarıdaki örnekte, otomatik olarak oluşturulan veritabanı EFCodeFirstDemo.MyContext ismine sahiptir. İsme bakarsanız, aşağıdaki kodda gösterildiği gibi EFCodeFirstDemo'nun ad alanı ve MyContext'in bağlam sınıfı adı olduğunu göreceksiniz.
public class MyContext : DbContext {
public MyContext() : base() {}
public virtual DbSet<Course> Courses { get; set; }
public virtual DbSet<Enrollment> Enrollments { get; set; }
public virtual DbSet<Student> Students { get; set; }
}
Veri tabanı ismi
Veritabanı adını bağlam sınıfının temel yapıcısında bir parametre olarak iletirseniz, Code First otomatik olarak yeniden bir veritabanı oluşturur, ancak bu sefer ad, yerel SQLEXPRESS veritabanı sunucusundaki temel yapıcıda parametre olarak geçirilen ad olur .
Aşağıdaki kodda, MyContextDB temel yapıcıda parametre olarak belirtilmiştir. Uygulamanızı çalıştırırsanız, MyContextDB adlı veritabanı yerel SQL sunucunuzda oluşturulacaktır.
public class MyContext : DbContext {
public MyContext() : base("MyContextDB") {}
public virtual DbSet<Course> Courses { get; set; }
public virtual DbSet<Enrollment> Enrollments { get; set; }
public virtual DbSet<Student> Students { get; set; }
}
Bağlantı Dizesi Adı
Bu, DbContext'e SQL Express veya LocalDb dışında bir veritabanı sunucusu kullanmasını söylemenin kolay bir yoludur. App.config dosyanıza bir bağlantı dizesi koymayı seçebilirsiniz.
Bağlantı dizesinin adı bağlamınızın adıyla eşleşiyorsa (ad alanı nitelendirmesi olsun ya da olmasın), parametre eksi yapıcı kullanıldığında DbContext tarafından bulunacaktır.
Bağlantı dizesi adı bağlamınızın adından farklıysa, bağlantı dizesi adını DbContext yapıcısına ileterek DbContext'e bu bağlantıyı Code First modunda kullanmasını söyleyebilirsiniz.
public class MyContext : DbContext {
public MyContext() : base("name = MyContextDB") {}
public virtual DbSet<Course> Courses { get; set; }
public virtual DbSet<Enrollment> Enrollments { get; set; }
public virtual DbSet<Student> Students { get; set; }
}
Yukarıdaki kodda, bağlam sınıfı bağlantı dizesinin parçacığı, temel yapıcıda bir parametre olarak belirtilmiştir.
Bağlantı dizesi adı "name =" ile başlamalıdır, aksi takdirde, bir veritabanı adı olarak kabul edilecektir.
Bu form, bağlantı dizesinin yapılandırma dosyanızda bulunmasını beklediğinizi açıkça belirtir. Verilen ada sahip bir bağlantı dizesi bulunmazsa bir istisna atılır.
<connectionStrings>
<add name = "MyContextDB"
connectionString = "Data Source =.;Initial Catalog = EFMyContextDB;Integrated Security = true"
providerName = "System.Data.SqlClient"/>
</connectionStrings>
App.config dosyasındaki bağlantı dizesindeki veritabanı adı EFMyContextDB. CodeFirst yeni birEFMyContextDB veritabanı veya var olanı kullan EFMyContextDB yerel SQL Server'daki veritabanı.
Etki Alanı Sınıfları
Şimdiye kadar EF'in modeli kendi varsayılan kurallarını kullanarak keşfetmesine izin verdik, ancak sınıflarımızın kurallara uymadığı ve daha fazla yapılandırma gerçekleştirebilmemiz gerektiği zamanlar olacaktır. Ancak, etki alanı sınıflarınızı EF'e ihtiyaç duyduğu bilgileri sağlayacak şekilde yapılandırarak bu kuralları geçersiz kılabilirsiniz. Etki alanı sınıflarınızı yapılandırmak için iki seçenek vardır -
- Veri Açıklamaları
- Fluent API
Veri Açıklamaları
DataAnnotations, sınıflarınızı en sık ihtiyaç duyulan yapılandırmaları vurgulayacak şekilde yapılandırmak için kullanılır. DataAnnotations, ASP.NET MVC gibi bir dizi .NET uygulaması tarafından da anlaşılır ve bu uygulamaların istemci tarafı doğrulamaları için aynı açıklamalardan yararlanmasına izin verir.
Aşağıda, öğrenci sınıfında kullanılan veri ek açıklamaları verilmiştir.
public class Enrollment {
[Key]
public int EnrollmentID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; }
public Grade? Grade { get; set; }
[ForeignKey("CourseID")]
public virtual Course Course { get; set; }
[ForeignKey("ID")]
public virtual Student Student { get; set; }
}
Fluent API
Çoğu model yapılandırması, basit veri açıklamaları kullanılarak yapılabilir. Akıcı API, veri açıklamalarıyla mümkün olmayan bazı daha gelişmiş yapılandırmalara ek olarak, veri açıklamalarının yapabileceği her şeyi kapsayan model yapılandırmasını belirlemenin gelişmiş bir yoludur. Veri açıklamaları ve akıcı API birlikte kullanılabilir.
Fluent API'ye erişmek için DbContext'te OnModelCreating yöntemini geçersiz kılarsınız. Şimdi öğrenci tablosundaki sütun adını FirstMidName'den FirstName'e aşağıdaki kodda gösterildiği gibi yeniden adlandıralım.
public class MyContext : DbContext {
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Entity<Student>().Property(s ⇒ s.FirstMidName)
.HasColumnName("FirstName");
}
public virtual DbSet<Course> Courses { get; set; }
public virtual DbSet<Enrollment> Enrollments { get; set; }
public virtual DbSet<Student> Students { get; set; }
}