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

10 Şubat 2013 Pazar

Fluent API - WithMany İlişkisi

Ref: Julia Lerman
Önceki haliyle sadece HasRequired metoduyla bağlandığında aşağıdaki gib oluşacaktı:
Buradaki durum bir makalenin kesinlikle bir bir Blog'a ait olması haliydi. Sol tarafta Post'un olduğunu düşünürseniz 1-1 ilişkiden söz ediyor oluruz. Bu ilişkide Blog eklenebilir çünkü Post olmasada olur ama Post HasRequired ile Blog özelliği belirtilmeksizin kayıt eklenemez.
Entities in 'Ctx_Blog.Posts' participate in the 'Post_Blog' relationship. 0 related 'Post_Blog_Target' were found. 1 'Post_Blog_Target' is expected.
Hatası alınır. Bu hatanın oluştuğu ekran şudur:
Buna göre Blog soldayken One To Zero Or Many kayıt girişi yapılabilir ki o da şöyledir:

Yukarıdaki gibi bir Blog birden fazla makaleye sahip olabilir. One To Many ilişkisini yaratmak için Fluent API'de WithMany metodunu kullanacağız. Bu metodu zincir bir linq cümlesinde HasRequired metodundan sonra görebiliriz. WithMany metodunu parametresiz çağırdığnız vakit Post tablosunda otomatik olarak bir FK oluşturacaktır. Bu FK, Blog tablosundaki Id ye işaret edecektir çünkü HasRequired metodu hangi tablonun Post tablosunda FK olarak yer aldığını gösterdik.
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
    modelBuilder.Entity<Post>()
                .HasRequired(p => p.Blog)
                .WithMany();
}
Resimde dikkat edilecek nokta ikinci oluşan FK dır(Blog_Id1).
Bu durum elbette istediğimiz hâl değildir. WithMany metodunda Blog sınıfının hangi özelliğinin Post sınıfından çoklu nesne taşıdığını işaretlemeliyiz. Yani; Post sınıfında bir Blog tanımlanması gerekir (HasRequired(p=>p.Blog) ve Blog sınıfında birden çok(many) Post barındıran özelliğin (WithMany(b=>b.Posts)) işaretlemesi yapılır.
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
    modelBuilder.Entity()
                .HasRequired(p => p.Blog)
                .WithMany(b=>b.Posts);
}
Buna göre aşağıdaki yapı oluşur:

Buna birde Post tablosundaki Blog_Id FK'sının adını FKBlogId gibi yaratmak istediğimizde önce Post sınıfına FKBlogId özelliğini ekleyelim:
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 FkBlogId { get; set; }
        public Blog Blog { get; set; }
    }
Bu durumda hem FKBlogId alanı oluşacak hem de HasRequired(p=>p.Blog) ilişkisinden dolayı FK olarak Blog_Id oluşacaktır. Aşağıdaki gibi bir ekran oluşacak ve yapacak diğer işimizi görebileceksiniz:
FKBlogId tabloda oluştu ama Post-Blog ilişkisinde kullanacağımız FK'nın bu olacağını bildirmemiz gerekiyor o da HasForeignKey metoduyla şöyle yapılır:
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
    modelBuilder.Entity()
        .HasRequired(p => p.Blog)
        .WithMany(b=>b.Posts)
        .HasForeignKey(p=>p.FkBlogId);
}


Tüm Kod:
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 b = new Blog() {
                BloggerName = "CemT",
                Title = "Notlarımdan",
                Posts = new[]{
                    new Post() {Title="Başlık 1", Content = "İçerik 1",DateCreated = DateTime.Now},
                    new Post() {Title="Başlık 2", Content = "İçerik 2",DateCreated = DateTime.Now}
                }
            };
            ctx.Blogs.Add(b);
            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)
                .WithMany(b=>b.Posts)
                .HasForeignKey(p=>p.FkBlogId);
        }
        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 FkBlogId { get; set; }
        public Blog Blog { get; set; }
    }
}

Hiç yorum yok: