【问题标题】:Entity Framework relationship with two foreign keys具有两个外键的实体框架关系
【发布时间】:2018-05-03 18:26:38
【问题描述】:

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

基本上Foo 是主表。 Bar 表是可选的。它们通过两列连接。 key1key2 对是唯一的。把它想象成一个父子关系,一个父母只能有一个孩子:

数据实体如下所示:

[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。 Foo 的列名称与Bar 中的主键完全一样。但它不起作用。

所以我尝试指定外键:

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

上面写着:

"指定的列数必须与主键数匹配 列”

哇?如何?怎么会?呃……

我也试过了:

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

所以我的问题是:

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

  2. 我该怎么办?

【问题讨论】:

  • 这与您的假设相反。 Foo必需Bar可选,因此Fooprincipal(父),Bar 是从属(子),所以Bar 应该有FK 指向Foos PK。
  • 在EF6中,你只能通过主键引用其他实体,所以两个实体应该共享FooId,你根本不能使用Key1Key2
  • @GertArnold wait wait wait.. 所以你是说我应该将FooId 列添加到Bar 表中?因为在这种情况下我不确定我是否能够在数据库中创建 FK?
  • 嗯,它的名字可以是任何东西,但它应该是shared primary key association

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


【解决方案1】:

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

也就是说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 的外键。您可能仍然可以通过 LINQ 查询中的子密钥加入。

【讨论】:

    猜你喜欢
    • 2015-08-01
    • 1970-01-01
    • 2017-07-20
    • 1970-01-01
    • 1970-01-01
    • 2020-07-08
    • 1970-01-01
    • 2017-10-27
    • 2019-04-15
    相关资源
    最近更新 更多