Aracılığıyla paylaş


İlişkiler, gezinti özellikleri ve yabancı anahtarlar

Bu makalede, Entity Framework'ün varlıklar arasındaki ilişkileri nasıl yönettiğine genel bir bakış verilmektedir. Ayrıca ilişkileri eşleme ve işleme konusunda da bazı yönergeler sağlar.

EF'de ilişkiler

İlişkisel veritabanlarında, tablolar arasındaki ilişkiler (ilişkilendirme olarak da adlandırılır) yabancı anahtarlar aracılığıyla tanımlanır. Yabancı anahtar (FK), iki tablodaki veriler arasında bağlantı kurmak ve zorlamak için kullanılan bir sütun veya sütun birleşimidir. Genellikle üç ilişki türü vardır: bire bir, bire çok ve çoka çok. Bire çok ilişkisinde yabancı anahtar, ilişkinin çok sonunu temsil eden tabloda tanımlanır. Çoka çok ilişkisi, birincil anahtarı her iki ilişkili tablonun yabancı anahtarlarından oluşan üçüncü bir tablo (birleşim veya birleştirme tablosu olarak adlandırılır) tanımlamayı içerir. Bire bir ilişkide, birincil anahtar ek olarak yabancı anahtar işlevi görür ve her iki tablo için de ayrı bir yabancı anahtar sütunu yoktur.

Aşağıdaki görüntüde, bire çok ilişkisine katılan iki tablo gösterilmektedir. Bölüm tablosuna bağlayanDepartmentID sütununu içerdiğinden, Kurs tablosu bağımlı tablodur.

Department and Course tables

Entity Framework'te bir varlık, ilişkilendirme veya ilişki aracılığıyla diğer varlıklarla ilişkilendirilebilir. Her ilişki, bu ilişkideki iki varlık için varlık türünü ve türün çokluğunu (bir, sıfır veya bir veya çok) açıklayan iki uç içerir. İlişki, ilişkideki hangi sonun asıl rol olduğunu ve hangilerinin bağımlı bir rol olduğunu açıklayan bir bilgi kısıtlaması tarafından yönetilebilir.

Gezinti özellikleri, iki varlık türü arasındaki ilişkide gezinmek için bir yol sağlar. Her nesne, katıldığı her ilişki için bir gezinti özelliğine sahip olabilir. Gezinti özellikleri, bir başvuru nesnesi (çokluk bir veya sıfır ya da bir ise) veya bir koleksiyon (çok fazlaysa) döndürerek ilişkilerde her iki yönde de gezinmenize ve bunları yönetmenize olanak sağlar. Tek yönlü gezinti de seçebilirsiniz. Bu durumda gezinti özelliğini her ikisinde değil, ilişkiye katılan türlerden yalnızca birinde tanımlarsınız.

Modele veritabanındaki yabancı anahtarlara eşlenen özelliklerin eklenmesi önerilir. Yabancı anahtar özellikleri dahilken, bağımlı bir nesnedeki yabancı anahtar değerini değiştirerek ilişki oluşturabilir veya değiştirebilirsiniz. Bu tür bir ilişkilendirme, yabancı anahtar ilişkilendirmesi olarak adlandırılır. Bağlantısı kesilmiş varlıklarla çalışırken yabancı anahtarların kullanılması daha da önemlidir. 1'e 1 veya 1-0 ile çalışırken... 1 ilişki, ayrı bir yabancı anahtar sütunu yoktur, birincil anahtar özelliği yabancı anahtar işlevi görür ve her zaman modele dahil edilir.

Yabancı anahtar sütunları modele dahil edilmediğinde, ilişkilendirme bilgileri bağımsız bir nesne olarak yönetilir. İlişkiler yabancı anahtar özellikleri yerine nesne başvuruları aracılığıyla izlenir. Bu tür bir ilişkilendirme, bağımsız ilişkilendirme olarak adlandırılır. Bağımsız bir ilişkilendirmeyi değiştirmenin en yaygın yolu, ilişkilendirmeye katılan her varlık için oluşturulan gezinti özelliklerini değiştirmektir.

Modelinizde bir veya her iki ilişkilendirme türünü kullanmayı seçebilirsiniz. Ancak, yalnızca yabancı anahtarlar içeren bir birleştirme tablosuyla bağlanan çoka çok ilişkisine sahipseniz, EF bu kadar çok-çok ilişkisini yönetmek için bağımsız bir ilişkilendirme kullanır.   

Aşağıdaki görüntüde Entity Framework Tasarım Aracı ile oluşturulmuş kavramsal bir model gösterilmektedir. Model, bire çok ilişkisine katılan iki varlık içerir. Her iki varlık da gezinti özelliklerine sahiptir. Kurs bağımlı varlıktır ve DepartmentID yabancı anahtar özelliği tanımlanmıştır.

Department and Course tables with navigation properties

Aşağıdaki kod parçacığı, Code First ile oluşturulan modeli gösterir.

public class Course
{
  public int CourseID { get; set; }
  public string Title { get; set; }
  public int Credits { get; set; }
  public int DepartmentID { get; set; }
  public virtual Department Department { get; set; }
}

public class Department
{
   public Department()
   {
     this.Courses = new HashSet<Course>();
   }  
   public int DepartmentID { get; set; }
   public string Name { get; set; }
   public decimal Budget { get; set; }
   public DateTime StartDate { get; set; }
   public int? Administrator {get ; set; }
   public virtual ICollection<Course> Courses { get; set; }
}

İlişkileri yapılandırma veya eşleme

Bu sayfanın geri kalanı, ilişkileri kullanarak verilere erişme ve verileri işleme konularını kapsar. Modelinizdeki ilişkileri ayarlama hakkında bilgi için aşağıdaki sayfalara bakın.

İlişkileri oluşturma ve değiştirme

Yabancı anahtar ilişkisinde, ilişkiyi değiştirdiğinizde, durumu olan EntityState.Unchanged bağımlı bir nesnenin durumu olarak EntityState.Modifieddeğişir. Bağımsız bir ilişkide, ilişkiyi değiştirmek bağımlı nesnenin durumunu güncelleştirmez.

Aşağıdaki örneklerde, ilgili nesneleri ilişkilendirmek için yabancı anahtar özelliklerinin ve gezinti özelliklerinin nasıl kullanılacağı gösterilmektedir. Yabancı anahtar ilişkilendirmeleriyle, ilişkileri değiştirmek, oluşturmak veya değiştirmek için iki yöntemden birini kullanabilirsiniz. Bağımsız ilişkilendirmeler ile yabancı anahtar özelliğini kullanamazsınız.

  • Aşağıdaki örnekte olduğu gibi yabancı anahtar özelliğine yeni bir değer atayarak.

    course.DepartmentID = newCourse.DepartmentID;
    
  • Aşağıdaki kod, yabancı anahtarı null olarak ayarlayarak bir ilişkiyi kaldırır. Yabancı anahtar özelliğinin null atanabilir olması gerektiğini unutmayın.

    course.DepartmentID = null;
    

    Dekont

    Başvuru eklenen durumdaysa (bu örnekte, kurs nesnesi), başvuru gezinti özelliği SaveChanges çağrılana kadar yeni bir nesnenin anahtar değerleriyle eşitlenmez. Nesne bağlamı kaydedilene kadar eklenen nesneler için kalıcı anahtarlar içermediğinden eşitleme gerçekleşmez. İlişkiyi ayarlar ayarlamaz yeni nesnelerin tam olarak eşitlenmesi gerekiyorsa, aşağıdaki yöntemlerden birini kullanın.*

  • Gezinti özelliğine yeni bir nesne atayarak. Aşağıdaki kod, bir kurs ile departmentarasında bir ilişki oluşturur. Nesneler bağlama bağlıysa, course koleksiyonuna department.Courses da eklenir ve nesnedeki course ilgili yabancı anahtar özelliği departmanın anahtar özellik değerine ayarlanır.

    course.Department = department;
    
  • İlişkiyi silmek için gezinti özelliğini olarak nullayarlayın. .NET 4.0'ı temel alan Entity Framework ile çalışıyorsanız, null olarak ayarlamadan önce ilgili ucun yüklenmesi gerekir. Örnek:

    context.Entry(course).Reference(c => c.Department).Load();
    course.Department = null;
    

    .NET 4.5'i temel alan Entity Framework 5.0'dan başlayarak, ilgili ucu yüklemeden ilişkiyi null olarak ayarlayabilirsiniz. Aşağıdaki yöntemi kullanarak geçerli değeri null olarak da ayarlayabilirsiniz.

    context.Entry(course).Reference(c => c.Department).CurrentValue = null;
    
  • Varlık koleksiyonundaki bir nesneyi silerek veya ekleyerek. Örneğin, koleksiyona department.Courses türünde Course bir nesne ekleyebilirsiniz. Bu işlem, belirli bir kurs ile belirli bir arasında bir departmentilişki oluşturur. Nesneler bağlama bağlıysa, bölüm başvurusu ve kurs nesnesinde yabancı anahtar özelliği uygun departmentolarak ayarlanır.

    department.Courses.Add(newCourse);
    
  • yöntemini kullanarak ChangeRelationshipState iki varlık nesnesi arasındaki belirtilen ilişkinin durumunu değiştirin. Bu yöntem en yaygın olarak N Katmanlı uygulamalar ve bağımsız bir ilişkilendirmeyle çalışırken kullanılır (yabancı anahtar ilişkilendirmesiyle kullanılamaz). Ayrıca, bu yöntemi kullanmak için, aşağıdaki örnekte gösterildiği gibi adresine açılan ObjectContextliste oluşturmanız gerekir.
    Aşağıdaki örnekte, Eğitmenler ve Kurslar arasında çoka çok ilişki vardır. ChangeRelationshipState yöntemini çağırmak ve parametresini EntityState.Added geçirmek, SchoolContext iki nesne arasına bir ilişki eklendiğini bildirir:

    
    ((IObjectContextAdapter)context).ObjectContext.
      ObjectStateManager.
      ChangeRelationshipState(course, instructor, c => c.Instructor, EntityState.Added);
    

    Bir ilişkiyi güncelleştiriyorsanız (yalnızca ekliyorsanız) yenisini ekledikten sonra eski ilişkiyi silmeniz gerektiğini unutmayın:

    ((IObjectContextAdapter)context).ObjectContext.
      ObjectStateManager.
      ChangeRelationshipState(course, oldInstructor, c => c.Instructor, EntityState.Deleted);
    

Yabancı anahtarlar ve gezinti özellikleri arasındaki değişiklikleri eşitleme

Yukarıda açıklanan yöntemlerden birini kullanarak bağlama bağlı nesnelerin ilişkisini değiştirdiğinizde, Entity Framework'ün yabancı anahtarları, başvuruları ve koleksiyonları eşitlenmiş durumda tutması gerekir. Entity Framework, proxy'ler içeren POCO varlıkları için bu eşitlemeyi (ilişki düzeltme olarak da bilinir) otomatik olarak yönetir. Daha fazla bilgi için bkz . Proxy'lerle çalışma.

POCO varlıklarını proxy'ler olmadan kullanıyorsanız, bağlamdaki ilgili nesneleri eşitlemek için DetectChanges yönteminin çağrıldığından emin olmanız gerekir. Aşağıdaki API'lerin bir DetectChanges çağrısını otomatik olarak tetiklediğini unutmayın.

  • DbSet.Add
  • DbSet.AddRange
  • DbSet.Remove
  • DbSet.RemoveRange
  • DbSet.Find
  • DbSet.Local
  • DbContext.SaveChanges
  • DbSet.Attach
  • DbContext.GetValidationErrors
  • DbContext.Entry
  • DbChangeTracker.Entries
  • Bir linq sorgusunu bir DbSet

Entity Framework'te, tanımlanan ilişkilendirme tarafından döndürülen varlıkla ilgili varlıkları yüklemek için genellikle gezinti özelliklerini kullanırsınız. Daha fazla bilgi için bkz . İlgili Nesneleri Yükleme.

Dekont

Yabancı anahtar ilişkisinde, bağımlı bir nesnenin ilgili bir ucunu yüklediğinizde, ilgili nesne şu anda bellekte olan bağımlının yabancı anahtar değerine göre yüklenir:

    // Get the course where currently DepartmentID = 2.
    Course course = context.Courses.First(c => c.DepartmentID == 2);

    // Use DepartmentID foreign key property
    // to change the association.
    course.DepartmentID = 3;

    // Load the related Department where DepartmentID = 3
    context.Entry(course).Reference(c => c.Department).Load();

Bağımsız bir ilişkilendirmede, bağımlı bir nesnenin ilgili sonu, şu anda veritabanında olan yabancı anahtar değerine göre sorgulanır. Ancak, ilişki değiştirildiyse ve bağımlı nesnedeki başvuru özelliği nesne bağlamında yüklenen farklı bir asıl nesneyi işaret ederse, Entity Framework istemcide tanımlandığı gibi bir ilişki oluşturmaya çalışır.

Eşzamanlılığı yönetme

Hem yabancı anahtar hem de bağımsız ilişkilendirmelerde eşzamanlılık denetimleri, modelde tanımlanan varlık anahtarlarını ve diğer varlık özelliklerini temel alır. Model oluşturmak için EF Tasarım Aracı kullanırken, özelliğin ConcurrencyMode eşzamanlılık açısından denetlenmesi gerektiğini belirtmek için özniteliğini sabit olarak ayarlayın. Model tanımlamak için Code First kullanırken eşzamanlılık denetimi yapmak istediğiniz özelliklerde ek açıklamayı kullanın ConcurrencyCheck . Code First ile çalışırken, özelliğin TimeStamp eşzamanlılık açısından denetlenmesi gerektiğini belirtmek için ek açıklamayı da kullanabilirsiniz. Belirli bir sınıfta yalnızca bir zaman damgası özelliğine sahip olabilirsiniz. Code First, bu özelliği veritabanındaki null atanamaz bir alanla eşler.

Eşzamanlılık denetimi ve çözümüne katılan varlıklarla çalışırken her zaman yabancı anahtar ilişkilendirmesini kullanmanızı öneririz.

Daha fazla bilgi için bkz . Eşzamanlılık Çakışmalarını İşleme.

Çakışan Anahtarlarla çalışma

Çakışan anahtarlar, anahtardaki bazı özelliklerin de varlıktaki başka bir anahtarın parçası olduğu bileşik anahtarlardır. Bağımsız bir ilişkilendirmede çakışan bir anahtarınız olamaz. Çakışan anahtarlar içeren yabancı anahtar ilişkilendirmesini değiştirmek için, nesne başvurularını kullanmak yerine yabancı anahtar değerlerini değiştirmenizi öneririz.