也许这是一个术语问题。在 Code first EF 中,EF 不允许您与 Principal 和 Dependent 建立 1:1 的关系,既具有彼此的外键,也不允许具有与 Principal 无关的主键的依赖项。在您的示例中,它看起来像是需要 2 个导航属性的情况。严格来说,这不是 1:1。因为您与同一张表有 2 个关系。您有 2 个 1:1 类型的关系。EF 认为这与 1 一样多。
如果您有真正的 1:1 关系,EF 将希望依赖项具有与主项相同的主键。
您可以在 Principle 和dependent 上定义 Multiple NAVIGATION 属性,从而产生索引。
因此,您可能希望调查多对 1 配置如果您希望主节点在数据库级别有一个可选外键,您需要稍后在迁移期间或使用脚本添加此 FK。但可以说,这最好被视为业务逻辑/规则检查,而不是原则上的可选 FK。所以是的,在准确匹配数据库上可能存在的内容方面存在限制。
但在代码优先的情况下,这实际上是必要的,这是值得怀疑的。
顺便说一句,这里的巧妙技巧是首先在 DB 中准确地建模您想要的代码。那里使用 EF Powertool nuget 从 DB 重新设计工程师 Codefirst。
EG mini DB 仅具有所需的表关系。在解决方案中创建一个新项目。安装实体框架 Powertools。然后在新项目中使用右键单击选项“首先从数据库逆向工程代码”。
如果可以的话,它显示了如何首先在代码中构建它.... :-)
我认为您想要实现的目标...请参阅代码示例(如果我误解了您的意思,请见谅)如果加载了 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>