我在连接FluentAPI中的两个表时遇到问题。它实际上是FluentAPI和Data Annotations的混合体。我看着这question,但它没有帮助我。我尝试使用Index
,组成了唯一的密钥。
基本上Foo
是主表。 Bar
表是可选的。它们通过两列连接。 key1
和key2
对是唯一的。将其视为父子关系,其限制是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
需要Foo
。 Foo
有可选的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 });
所以我的问题是:
为什么我的解决方案不起作用?我确实有指定的复杂键
我该如何解决?
答案 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查询中的子密钥加入。