Aklımda Kalası Kelimeler

* давайте работать вместе
* Zarf ve Mazruf, Zerafet(xHoyratlık) ile aynı kökten(za-ra-fe) gelir
* Bedesten
* Suç subuta ermiştir - Suç sabit olmuştur
HasRequired etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
HasRequired etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

10 Şubat 2013 Pazar

Fluent API - HasRequired - One To Zero Or One ilişkisi

Ref: Julia Lerman
"Bir makale daima bir Blog'a ait olmalıdır" tanımını gerçeklemek için Blog ve Post sınıfları arasında şöyle bir ilişki tanımlanmalıdır:
public class Blog
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string BloggerName { get; set; }
        public virtual ICollection<Post> Posts { get; set; }
    }
    public class Post
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public DateTime DateCreated { get; set; }
        public string Content { get; set; }
        public int BlogId { get; set; }
        public Blog Blog { get; set; }
    }
Buna göre şu DB oluşur. Dikkat etmeniz gereken yer BlogId alanının Not Null olarak Post tablosunda oluşmasıdır. Bunu yapanın public int BlogId { get; set; } özelliği olduğuna dikkat ediniz.


Eğer Post içindeki BlogId özelliğini "EF zaten public Blog Blog { get; set; } özelliğini görür görmez oluşturacak" derseniz
O zamanda Null bırakılabilir bir makale girişi yapabiliyor olacaksınız. One - To - [Zero Or One](1-0..1) ilişkisini solda Blog olacak şekilde kurdunuz demektir.

Peki public int BlogId { get; set; } özelliğini sınıf içinde tanımlamadan Fluent API ile OnModelCreating metodunda tanımlamak isterseniz:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
}
Post sınıfındaki Blog özelliğinin gerekli olduğunu belirmek için:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Post>().HasRequired(p => p.Blog);
}

Son şekliyle kodumuz:
using System;
using System.Collections.Generic;
using System.Data.Entity;

namespace caFluentAPI {
    class Program {
        static void Main(string[] args) {
            var ctx = new Ctx_Blog();
            var v = new Blog() {
                    BloggerName = "CemT",
                    Title = "Notlarımdan",
                };
            ctx.Blogs.Add(v);
            ctx.SaveChanges();
        }
    }

    public class Ctx_Blog : DbContext {
        public Ctx_Blog() : base("name=cnn") {
            Database.SetInitializer<Ctx_Blog>(new DropCreateDatabaseAlways<Ctx_Blog>());
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder) {
            modelBuilder.Entity<Post>().HasRequired(p => p.Blog);
        }
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }
    }

    public class Blog
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string BloggerName { get; set; }
        public virtual ICollection<Post> Posts { get; set; }
    }
    public class Post
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public DateTime DateCreated { get; set; }
        public string Content { get; set; }
        //public int BlogId { get; set; }
        public Blog Blog { get; set; }
    }
}

8 Şubat 2013 Cuma

Fluent API Nedir, Ne Değildir?

Referans: Configuring Relationships with the Fluent API

Yukarıdaki bağlantıdan edindiklerimi aktaracağım ve birazda okuduğum, izlediklerimden serpiştireceğim. Maksat kavrama seviyesini idrak düzeyine eriştirmek.
Julia Lerman'ın kitapları var Code First ve DbContext üzerine. Gördümki FLUENT API yi kullanmak Annotations'dan hem daha okunaklı hem de tüm yetenekleri barındırması açısından tercih sebebi.

Tablolar arasında ilişkileri Foreign Key ve Navigation özelliklerini kullanarak yapıyoruz. Bu ilişkileri vermek için Fluent API içinde HasRequired, HasOptinal ve HasMany metotlarını kullanıyoruz. Bu metotlar lambda ifadelerini parametre olarak alırlar.

HasKey metodu; tablonun Primary Key alanını ifade etmek için kullanılır ve POCO sınıfında bu değer otomatik oluşturuluyorsa girilmez.
HasRequired metodu; tablo alanlarının boş bırakılamayacağını işaretlemekte kullanılır.
HasMany metodu; bir kolleksiyona yönlenen lambda ifadesi içerir.
HasForeignKey metodu; tabloya başka bir tablonun PK alanını vermek için kullanılır.
http://stackoverflow.com/a/7644906/104085


Tersi yönündeki yönelmeyi de WithRequired, WithOptinal, WithMany metotları sağlar.

VT'yi oluşturmak için kullanacağımız Provider ve VT erişimi için kullanıcı bilgilerini .Config dosyasında tutalım ve DbContext'in yaratıcı metoduna parametre olarak verelim:
<connectionStrings>
    <add name="cnn" connectionString="data source=.; Initial Catalog=cop; Integrated Security=SSPI;" providerName="System.Data.SqlClient" />
  </connectionStrings>

DbContext'i miras alan ve tüm DbSet'leri tutarak VT'nin yaratılması öncesi eylemleri yapacağımız sınıfta VT'yi her defasında silip tekrar yaratalım:
public class Kontext : DbContext
    {
        public Kontext()
            : base("name=cnn")
        {
            this.Database.Delete(); //VT yi silelim
            this.Database.CreateIfNotExists(); //Silinmiş VTyi yaratalım
        }
    }

HasRequired

Veritabanını oluşturmak için aşağıdaki kodlama yapılır ve One To One tablo yapısı oluşturulur. Burada principal Adres olacak ve Kisi sınıfında FK olarak yer alacak.

Eğer Adres bilgisi(Kisi->IkametAdresi) girilmeden Kisi nesnesini VT ye giremezsiniz. İşte aşağıdaki hata sonucu:

Böyle bir ilişkide eğer önce Foreign Key nesnesini girilmeli:


Aşağıdaki POCO yapısına göre daha aşağıda oluşan VT'yi göreceksiniz:
public class Kontext : DbContext
    {
        public Kontext()
            : base("name=cnn")
        {
            this.Database.Delete();
            this.Database.CreateIfNotExists();
        }

        #region DbSets
        public DbSet Kisiler { get; set; }
        public DbSet Adresler { get; set; }
        public DbSet Meslekler { get; set; }
        #endregion

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity().HasKey(p => p.Id)
                        .HasRequired(p => p.FaturaAdresleri)
                        .WithMany();
        }
    }

    public class Kisi
    {
        public int Id { get; set; }
        public string Adi { get; set; }
        public virtual ICollection Mesleks { get; set; }
        public virtual ICollection FaturaAdresleri { get; set; }
        public virtual ICollection TeslimatAdresleri { get; set; }
    }

    public class Meslek
    {
        public int Id { get; set; }
        public string Adi { get; set; }
        public virtual ICollection Kisis { get; set; }
    }

    public class Adres
    {
        public int Id { get; set; }
        public string AcikAdres { get; set; }
    }


Saat 00:35. Yarın ola hayrola ...

One to Zero or One


One to Zero or Many