おそらく用語の問題です。コード ファースト EF では、EF では、プリンシパルと依存関係の両方で相互に外部キーを使用したり、プリンシパルとは無関係の独自の主キーを持つ依存関係との 1 対 1 の関係を持つことはできません。あなたの例では、2 つのナビゲーション プロパティが必要な場合のようです。厳密に言えば、1:1 ではありません。同じテーブルに 2 つの関係があるためです。タイプ1:1の2つの関係があります。EFはこれを多対1と見なします。
真の 1 対 1 の関係がある場合、EF は依存関係にプライマリ キーと同じプライマリ キーを持たせたいと考えます。
原則と従属の両方で複数の NAVIGATION プロパティを定義できます。これにより、インデックスが作成されます。
そのため、多対 1 構成を調査することをお勧めします。プライマリに DB レベルで OPTINAL 外部キーを持たせたい場合は、後で移行中またはスクリプトを使用してこの FK を追加する必要があります。しかし、間違いなく、これはプリンシパルの OPTIONAL FK ではなく、ビジネス ロジック/ルール チェックとして最もよく見られます。そうです、DB で可能なことを正確に一致させるには制限があります。
しかし、コードファーストのシナリオで実際に必要かどうかは疑問です。
ここでの巧妙なトリックは、最初にコードで必要なものをDBで正確にモデル化することです。EF Powertool nuget を使用して、DB から Codefirst を再構築します。
目的のテーブル関係のみを含む EG ミニ DB。ソリューションで新しいプロジェクトを作成します。Entity Framework Powertools をインストールします。次に、新しいプロジェクトで右クリック オプションを使用して、「最初に DB からコードをリバース エンジニアリング」します。
可能であれば、最初にコードでそれを構築する方法を示しています.... :-)
あなたが達成したいと思うこと...コードサンプルを参照してください(あなたが作っている点を誤解していたらごめんなさい)コードはNUGETがロードされた場合に実行されるべきです
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 Main
{
public int MainId { get; set; }
public string BlaMain { set; get; }
public int? Sub1Id { set; get; } // Must be nullable since we want to use EF foreign key
public int? Sub2Id { set; get; } // Must be nullable since we want to use EF foreign key
public virtual Sub Sub1 { get; set; } // Reverse navigation
public virtual Sub Sub2 { get; set; } // Reverse navigation
// you may also need
public virtual ICollection<Sub> Subs { get; set; }
}
public class Sub
{
public int SubId { get; set; } // Deliberately DIFFERENT KEY TO MAIN.... not 1:1 so this is possible
public string blasub { set; get; }
public int MainId { set; get; } //set in API , this the FK
public virtual Main Main { get; set; } // van to Principal
}
public class Context121 : DbContext
{
static Context121()
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<Context121>());
}
public Context121()
: base("Name=Demo") { } // webconfig required to match
public DbSet<Main> Mains { get; set; }
public DbSet<Sub> Subs { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Main>().HasKey(t => t.MainId)
.HasOptional(t => t.Sub1)
.WithMany()
.HasForeignKey(t=>t.Sub1Id) ; // tell EF the field is in POCO, use this please, otherwise it will create it.
modelBuilder.Entity<Main>()
.HasOptional(t => t.Sub2).WithMany()
.HasForeignKey(t=>t.Sub2Id);
modelBuilder.Entity<Sub>()
.HasKey(t => t.SubId)
.HasRequired(q => q.Main)
.WithMany()
.HasForeignKey(t => t.MainId);
}
}
}
ウェブコンフィグ....
<connectionStrings>
<add name="Demo" connectionString="Data Source=localhost;Initial Catalog=Demo;Integrated Security=True;MultipleActiveResultSets=True;App=EntityFramework"
providerName="System.Data.SqlClient" />
</connectionStrings>