2013-02-11 18 views
7

Varlığımdan birinde tersine gezinme konusunda sorun yaşıyorum.Entity Framework Fluent API'si ile birebir ilişki

Ben şu iki nesne vardır:

public class Candidate 
{ 
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public long CandidateId { get; set; } 
    .... 

    // Reverse navigation 
    public virtual CandidateData Data { get; set; } 
    ... 

    // Foreign keys 
    .... 
} 

public class CandidateData 
{ 
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public long CandidateDataId { get; set; } 

    [Required] 
    public long CandidateId { get; set; } 

    // Foreign keys 
    [ForeignKey("CandidateId")] 
    public virtual Candidate Candidate { get; set; } 
} 

Şimdi CandidateData nesne üzerinde benim yabancı anahtar navigasyon çalışıyor

. Aday nesnenin çalışması için geri navigasyonu almamda sorun yaşıyorum (eğer mümkünse). Ben CandidateId bağlantı veren iki sütun olsun

Bu veritabanında dışında çalışan yakın
protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 

    modelBuilder.Entity<Candidate>() 
     .HasOptional(obj => obj.Data) 
     .WithOptionalPrincipal(); 

    base.OnModelCreating(modelBuilder); 
} 

:

Bu benim OnModelCreating fonksiyonudur. POCO nesnesinden bir tane aldığımda, bir başka sütun aldığım Candidate_CandidateId modelBuilder tarafından yaratıldığını varsayıyorum.

Şu anda sessizim. Birisi neler olup bittiğine biraz ışık tutabilir mi?

+0

Neden [Zorunlu] public long CandidateId {get; set; } Onu kaldırın ve sorunlarınız gitmiş olacak –

+0

Bence ilişkiniz modelBuilder.Entity () .HasOptional (obj => obj.Data) olmalıdır .WithRequired (e => e.Candidate); BTW: akıcı api ve niteliklerini karıştırmaya çalışmayın. – tschmit007

cevap

13

Birebir sorun .... Sorun, EF ve KOD İlk olarak, 1: 1 olduğunda, bağımlı için birincil başvuruda bulunan bir Ana anahtar olması. Bir DB'yi başka bir şekilde tanımlayabilirsiniz ve bir DB ile gerçekten olsa bile, Birincilde OPTIONAL FK'ye sahip olabilirsiniz. EF bu kısıtlamayı önce Kod'da yapar. Yeter Adil Bence ...

denemek yerine bu: Eğer :-)

using System.ComponentModel.DataAnnotations; 
using System.ComponentModel.DataAnnotations.Schema; 
using System.Data.Entity; 
namespace EF_DEMO 
{ 
class FK121 
{ 
    public static void ENTRYfk121(string[] args) 
    { 
     var ctx = new Context121(); 
     ctx.Database.Create(); 
     System.Console.ReadKey(); 
    } 
} 
public class Candidate 
{ 
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]// best in Fluent API, In my opinion.. 
    public long CandidateId { get; set; } 
// public long CandidateDataId { get; set; }// DONT TRY THIS... Although DB will support EF cant deal with 1:1 and both as FKs 
    public virtual CandidateData Data { get; set; } // Reverse navigation 

} 
public class CandidateData 
{ 
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] // best in Fluent API as it is EF/DB related 
    public long CandidateDataId { get; set; } // is also a Foreign with EF and 1:1 when this is dependent 
    // [Required] 
    // public long CandidateId { get; set; } // dont need this... PK is the FK to Principal in 1:1 
    public virtual Candidate Candidate { get; set; } // yes we need this 
} 
public class Context121 : DbContext 
{ 
    static Context121() 
    { 
     Database.SetInitializer(new DropCreateDatabaseIfModelChanges<Context121>()); 
    } 
    public Context121() 
     : base("Name=Demo") { } 
    public DbSet<Candidate> Candidates { get; set; } 
    public DbSet<CandidateData> CandidateDatas { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Candidate>(); 

     modelBuilder.Entity<CandidateData>() 
        .HasRequired(q => q.Candidate) 
        .WithOptional(p=>p.Data) // this would be blank if reverse validation wasnt used, but here it is used 
        .Map(t => t.MapKey("CandidateId")); // Only use MAP when the Foreign Key Attributes NOT annotated as attributes 
    } 
} 

}

+0

Teşekkürler, bu benim için problemi az çok çözdü. Yine de CandidateId alanımın anında ve Candidate nesnesini yüklemeye gerek kalmadan düzenlemesi için kullanılabilir olmasını isterim. (Ya da bunu yanlış yorumluyorum?) Tekrar teşekkürler, William. – William

+0

Eğer hala yabancı anahtarı istiyorsanız, CandidateId'i CandidateData'da bir özellik olarak tutabilir ve .Map (t => t.MapKey ("CandidateId")) kullanmak yerine .HasForeignKey (t => t.CandidateId) Bu işe yaramaz mı? –

+0

@NathanaelSchulte Maalesef çalışmıyor. Bunu neden yapamıyorsunuz, hiç bir fikrim yok. .HasForeignKey() yöntemine yalnızca birçoğu kullanılırken erişilebilir. Phil Soady'nin yaklaşımıyla ilgili problem, yabancı anahtar olan CandidateId'in, modelin açık bir özelliği olarak açıkta bulunmamasıdır, yani CandidateId, CandidateData sınıfında tanımlanamaz. – Aernor

-2

katılmıyorum eğer ihmal edebilirsiniz yolda birkaç görüşler ekledik IS Yabancı anahtar aşağıdaki gibi oluşturulmalıdır: .Map (t => t.MapKey ("CandidateDataId")) çünkü bu yabancı anahtar, Aday tabloya yerleştirilir.

Waht?