实体框架与两个外键

时间:2018-05-03 18:26:39

标签: c# .net entity-framework entity-framework-6 ef-fluent-api

我在连接FluentAPI中的两个表时遇到问题。它实际上是FluentAPI和Data Annotations的混合体。我看着这question,但它没有帮助我。我尝试使用Index,组成了唯一的密钥。

基本上Foo是主表。 Bar表是可选的。它们通过两列连接。 key1key2对是唯一的。将其视为父子关系,其限制是1父母只能有1个孩子:

数据实体如下所示:

[Table("foo")]
public class Foo
{
    [Key]
    [Column("pk", TypeName = "int")]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int FooId { get; set; }

    [Column("key1", TypeName = "int")]
    public int Key1 { get; set; }
    [Column("key2", TypeName = "int")]
    public int Key2 { get; set; }

    public Bar Bar { get; set; }
}

[Table("bar")]
public class Bar
{
    [Key]
    [Column("key1", TypeName = "int", Order = 1)]
    public int Key1 { get; set; }
    [Key]
    [Column("key2", TypeName = "int", Order = 2)]
    public int Key2 { get; set; }

    public Foo Foo { get; set; }
}    

以下是我尝试连接它们的方式:

modelBuilder.Entity<Bar>().HasRequired(p => p.Foo).WithOptional(p => p.Bar);

有什么问题? Bar需要FooFoo有可选的Bar。 &lt; ---这应该足够了,因为Foo的列名与Bar中的主键完全相同。但它不起作用。

所以我尝试指定外键:

modelBuilder.Entity<Bar>().HasRequired(p => p.Foo).WithOptional(p => p.Bar).Map(p => p.MapKey(new[] { "key1", "key2" }));

它说:

  

“指定的列数必须与主键数相匹配   列“

Whaaaat?怎么样?怎么会?呃..

我也尝试过:

modelBuilder.Entity<Bar>().HasIndex(table => new { table.Key1, table.Key2 });  

所以我的问题是:

  1. 为什么我的解决方案不起作用?我确实有指定的复杂键

  2. 我该如何解决?

1 个答案:

答案 0 :(得分:0)

这有点复杂,我可能在这里完全错了,但根据我的经验,EntityFramework关系不会那样工作。在我看来,如果Foo 需要而Bar是可选,那么每个Bar应该有一种方法可以根据Foo的 pk唯一地连接回Foo value。

也就是说Bar应定义为:

[Table("bar")]
public class Bar
{
    [Key]
    [Column("key1", TypeName = "int", Order = 1)]
    public int Key1 { get; set; }
    [Key]
    [Column("key2", TypeName = "int", Order = 2)]
    public int Key2 { get; set; }
    public int FooId { get; set; }

    public Foo Foo { get; set; }
}    

然后,您需要在关系描述中使用此FooId,而不是Bar中包含的复合键。 EntityFramework始终要求我加入父POCO的整个主键,父POCO必须是子POCO的外键。您仍然可以通过LINQ查询中的子密钥加入。