EF - WithOptional - 左外连接?

时间:2017-04-05 12:17:00

标签: c# entity-framework entity-framework-6

使用以下一对一模型,两者都具有导航属性: -

public class Foo
{
    public int Id { get; set; }

    public virtual Bar Bar { get; set; }
}

public class Bar
{
    public int Id { get; set; }

    public virtual Foo Foo { get; set; }
}

Foo 有一个可选的 Bar

Bar 有一个必需的 Foo

我在 Bar 上有以下映射: -

HasRequired(x => x.Foo)
      .WithOptional(x => x.Bar)
      .Map(x => x.MapKey("FooId"));

在名为'FooId'的 Bar 表中创建外键。

所有这些都可以正常工作,除非它在不需要的情况下为所有查询生成 Foo 的sql,其中“左外部加入”到 Bar

SELECT ..
[Extent2].[Id] AS [Id1]
FROM  [dbo].[Foo] AS [Extent1]
LEFT OUTER JOIN [dbo].[Bar] AS [Extent2] ON [Extent1].[Id] = [Extent2].[FooId]

仔细观察它只会返回Bar的Id。

Searching筹码我可以看到使用.WithMany代替.WithOptional的大多数建议,但我需要导航属性。

有什么建议吗?

1 个答案:

答案 0 :(得分:4)

这是一对一FK关联的标准行为,无法避免。 EF做的是在内部维护int? BarId实体的隐藏(阴影)属性,如Foo

摆脱LEFT OUTER JOIN并保持双向导航属性的唯一方法是,能够承担更改 Bar db模型(表)以使用(默认)基本上从流畅的配置中移除Map调用,以获得EF一对一模型Shared Primary Key Association

HasRequired(x => x.Foo)
    .WithOptional(x => x.Bar);

在此模型中,Bar表将不包含FooId FK列,而是PK列Id将不再具有身份,并且还将作为FK引用{{1} }表。

这样,EF就无需在Foo中维护BarId,因为它知道如果有相应的Foo,则BarId相同}}

如果您无法更改数据库设计,那么您运气不好 - 您必须使用Foo.Id,或者牺牲LEFT OUTER JOIN导航属性并将关系配置为你已经提到的单向一对多。