2012-04-11 11 views
11

Yabancı anahtar ilişkilerini kullanarak ilişki kurmaya çalıştığım iki öğeyi (birebir) takip ediyorum.Entity Framework Code First: Açıklamaları kullanarak One-To-One yabancı anahtar ilişkilendirmesini ayarlama

public class StandardRack { 
    public int Id {get;set} 
    public StandardRelay StandardRelay {get;set} 
} 

public class StandardRelay { 
    public int Id {get;set} 

    public int StandardRack_Id {get;set;} 
    [Required][ForeignKey("StandardRack_Id")] 
    public StandardRack StandardRack { get; set; } 
} 

Bu, ModelValidationException'ı atar. Böyle basit bir bire-bir çift yönlü ilişki neden yapılandırılamaz herhangi bir fikir.

Düzenleme:

System.Data.Entity.ModelConfiguration.ModelValidationException yakalandı İleti = Bir veya daha fazla doğrulama hataları modeli oluşturma sırasında tespit edilmiştir:

İşte

İstisna olan

System.Data.Edm.EdmAssociationEnd:: 'StandardRelay_StandardRack' ilişkisinde Role 'StandardRelay_StandardRack_Source' içinde çoğulluk geçerli değil. Bağımlı Rol özellikleri temel özellikler olmadığından Bağımlı Rolün çokluğunun üst sınırı * olmalıdır.

Kaynak = EntityFramework StackTrace: System.Data.Entity.ModelConfiguration.Edm.EdmModelExtensions.ValidateCsdl at System.Data.Entity.ModelConfiguration.Edm.EdmModelExtensions.ValidateAndSerializeCsdl (EdmModel modeli, XmlWriter yazar) de (EdmModel modeli) System.Data.Entity.Internal.LazyInternalContext.CreateModel de System.Data.Entity.DbModelBuilder.Build (DbConnection providerConnection) de System.Data.Entity.DbModelBuilder.Build (DbProviderManifest providerManifest, DbProviderInfo providerInfo) (LazyInternalContext internalContext de ) System.Data.Entity.Internal.RetryLazy 2.GetValue(TInput input) at System.Data.Entity.Internal.LazyInternalContext.InitializeContext() at System.Data.Entity.Internal.InternalContext.Initialize() at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) at System.Data.Entity.Internal.Linq.InternalSet 1.Initialize()System.Linq.Enumerable.ToList de System.Data.Entity.Internal.Linq.InternalSet 1.GetEnumerator() at System.Data.Entity.Infrastructure.DbQuery 1.System.Collections.Generic.IEnumerable.GetEnumerator() System.Collections.Generic.List 1..ctor(IEnumerable 1 koleksiyonu) de[ \ RailwayProjects \ RelayAnalysis \ TestApplication MainWindow.xaml.cs \: hattı 33 InnerException:

+0

Olası iç özel durumlar dahil olmak üzere 'ModelValidationException' ile ilgili ayrıntılı iletiyi gönderir misiniz? – Slauma

+0

Lütfen istisna için benim EDIT'ime bakın – Jatin

cevap

8

Yabancı anahtarın StandardRack_id değil Id olması gerektiğini düşünüyorum. Ayrıca, tembel yükleme kullanabilmek için sanal kullanmalısınız. Beni

using System.ComponentModel.DataAnnotations; 
using System.Data.Entity; 

namespace Racks 
{ 

    public class StandardRack 
    { 
     public int Id { get; set; } 
     public virtual StandardRelay StandardRelay { get; set; } 
    } 

    public class StandardRelay 
    { 
     public int Id { get; set; } 

     public int StandardRack_Id { get; set; } 

     [ForeignKey("Id")] 
     [Required] 
     public virtual StandardRack StandardRack { get; set; } 
    } 

    public class Context : DbContext 
    { 
     static Context() 
     { 
      Database.SetInitializer<Context>(null); 
     } 

     public DbSet<StandardRack> StandardRacks { get; set; } 
     public DbSet<StandardRelay> StandardRelays { get; set; } 

    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      var context = new Context(); 
      context.Database.Delete(); 
      context.Database.Create(); 

      var standardRack = new StandardRack(); 
      standardRack.StandardRelay = new StandardRelay(); 

      context.StandardRacks.Add(standardRack); 
      context.SaveChanges(); 
     } 
    } 
} 
+0

Arialdo, @Slauma, her ikinizin de önerdiği yaklaşımlar aynı Veritabanı yapısına, yani StandardRack'in Id sütununa StandardRelay'in yabancı anahtarının (Id) hedefi olarak hizmet eder. Arialdo'nun yaklaşımı ile gideceğim ve her iki cevap da işe yaramasına rağmen cevabını doğru olarak işaretleyeceğim. – Jatin

+0

+1 İyi fikir! Bu bire bir eşlemenin ek açıklamalarla da çalışmasını beklemiyordum. Eğer '[ForeignKey]' özniteliğini tamamen kaldırırsanız (ama [Gerekli] 'özniteliğini yerinde bırakın) da çalışıp çalışmadığını merak ediyorum. Bunu test ettin mi? – Slauma

+1

@Slauma, Yabancıyı çıkarsam bile, çalışır ve aynı veritabanı yapısını oluşturur. Bu yüzden Foreignkey tamamen terk edilebilir.Bana yardım ettiğin için ikinize de çok teşekkür ederim. – Jatin

23

bir D TestApplication.MainWindow.Window_Loaded (Obje gönderen, RoutedEventArgs e) en TSource] (IEnumerable`1 kaynağı) -bir-bir yabancı anahtar dernekleri Entitiy Framework tarafından desteklenmemektedir. Sen yabancı anahtarı çıkarın ve (bağımlı birincil anahtar aynı anda okul müdürüne dış anahtarıdır) paylaşılan birincil anahtarları kullanmalıdır: Akıcı API

public class StandardRack { 
    public int Id {get;set} 
    public StandardRelay StandardRelay {get;set} 
} 

public class StandardRelay { 
    public int Id {get;set} 
    public StandardRack StandardRack { get; set; } 
} 

Haritalama:

modelBuilder.Entity<StandardRack>() 
    .HasOptional(rack => rack.StandardRelay) 
    .WithRequired(relay => relay.StandardRack); 

(Burada bir StandardRack'un isteğe bağlı bir Röle'ye sahip olduğunu varsayardım.)

+0

Şahsen bu yaklaşımı yukarıda kaydedilen bir taneye tercih ediyorum: Veri tabanı-agnostik varlıkları severim, bu yüzden her zaman ek açıklamalardan kaçınmaya çalışırım. +1 –

+2

Ayrıca, not: tembel yükleme kullanmak için, 'sanal' ilkel olmayan özelliklerine eklemelisiniz. –

+0

Entity Framework ya da Code First tarafından özel olarak desteklenmiyor mu? Bu emin edmx içinde çalışır. –

3

edilir: Ayrıca, bu ilgili soruya bakın.

FK'nin Enitity'de açıkça tanımlanmadığını, ancak akıcı api kullanarak tanımlandığını unutmayın.

public class StandardRack { 
    public int Id {get;set} 
    public StandardRelay StandardRelay {get;set} 
} 

public class StandardRelay { 
    public int Id {get;set} 
    public StandardRack StandardRack { get; set; } 
} 


modelBuilder.Entity<StandardRack>() 
      .HasOptional(x => x.StandardRelay) 
      .WithOptionalPrincipal(y => y.StandardRack) 
      .Map(configurationAction: new Action<ForeignKeyAssociationMappingConfiguration>(x => x.MapKey("StandardRack_Id"))); 

akıcı API StandardRelay sütunu StandardRack_Id ekleyecektir.

WithOptionalPrincipal() yöntem adının oldukça ironik olduğunu unutmayın. WithOptionalDependent'un msdn dokümantasyonu bunu netleştirecektir.

+0

Kimse '.Map' ve' .MapKey''den bahsetmiyor, bunu gönderdiğiniz için teşekkürler! – Langdon

+0

Teşekkürler, zaman kurtarıcım! :-) – VikciaR