2013-02-11 6 views
7

エンティティのいずれかのリバースナビゲーションに問題があります。Entity Framework Fluent APIとの1対1の関係

私は、次の2つのオブジェクトがあります。

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; } 
} 

は今CandidateDataオブジェクト上の私の外部キーナビゲーションが正常に動作します。私は、(それが可能な場合でも)候補オブジェクトが動作するように逆のナビゲーションを得るのが難しいです。

これは私のOnModelCreating機能である:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 

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

    base.OnModelCreating(modelBuilder); 
} 

それは私がCandidateIdにリンク2つの列を取得するデータベースを除いて作業に近いのです。 POCOオブジェクトから取得したものを別の列に取得します。Candidate_CandidateId私はmodelBuilderによって作成されたものと想定しています。

私は今は静かです。誰かが何が起こっているかについていくつかの光を当てることができますか?

+0

なぜ追加フィールドを定義しますか [必須] public long CandidateId {get;セット; } これを削除すると問題がなくなります –

+0

あなたの関係はmodelBuilder.Entityである必要があります。().HasOptional(obj => obj.Data).WithRequired(e => e.Candidate); BTW:流暢なAPIと属性を混ぜないようにしてください。 – tschmit007

答えて

13

問題あり.... 問題はEFとCODEです。まず、プリンシパルを参照する主キーが従属するために、1:1の場合。あなたはDBを定義することはできますが、実際にはDBを使用することもできますが、プライマリにはオプションのFKを設定することもできます。 EFはコードでこの制限を最初に行います。私が思うに十分なフェア...

試してみてください代わりに、この:あなたは

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

ありがとう、これは多かれ少なかれ私の問題を解決しました。 CandidateIdフィールドを利用して、オンザフライで編集し、候補オブジェクトをロードする必要がなくても構いません。 (または私はこれを間違って解釈していますか?) もう一度、William。 – William

+0

外部キーが必要な場合は、CandidateDataをCandidateDataのプロパティとして保持し、.Map(t => t.MapKey( "CandidateId"))を呼び出す代わりに.HasForeignKey(t => t.CandidateId)を使用します。 それは動作しませんか? –

+0

@ NathanaelSchulte残念ながら、それは動作しません。なぜあなたはそれをすることができません、私は分かりません。 .HasForeignKey()メソッドは、多くを使用する場合にのみアクセス可能です。 phil soadによるアプローチの問題は、外部キーCandidateIdをモデルの明示的なプロパティとして公開しない、つまりCandidateDataクラスでCandidateIdを定義できないことです。 – Aernor

-2

:-)同意場合は、を無視して、途中でいくつかの意見を追加したIS外部キーは候補テーブルに配置されるため、外部キーは .Map(t => t.MapKey( "CandidateDataId"))として作成する必要があると思います。

あなたはどう思いますか?

関連する問題