0

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

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

数据实体如下所示:

[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确实需要Foo. Foo有可选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. 我怎么能爱它?

4

1 回答 1

1

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

也就是说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 查询中的子键加入。

于 2018-05-03T21:17:30.007 回答