2017-04-05 145 views
8

用下面的一对一个模特,都与导航性能: -EF - WithOptional - 左外连接?

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; } 
} 

有一个可选的酒吧

酒吧有需要

我有以下映射上酒吧: -

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

它创建的名为酒吧表的外键 'FooId'。

所有这一切工作正常,但其与“左外部联接”到酒吧上所有查询生成的sql其不需要的时候。

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

仔细看它只会返回酒吧的ID。

Searching stack我可以看到大多数建议使用.WithMany而不是.WithOptional,但我需要导航属性。

有什么建议吗?

+0

如果你考虑一下,除非你正在做一个共享主键,否则真的没有1:1这样的东西,因为键的性质必须是唯一的。当然,你可以对1:*设置一个唯一的约束来创建一个有效的1:1,但这是一种“虚拟”1:1,而不是一个真实的物理约束。EF不支持这样的约束,所以这是不可能的。这就是加入的原因,因为EF只能假设这是1:* –

回答

4

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

只有这样,才能摆脱LEFT OUTER JOIN S和保持双向导航性能是如果你能负担得起改变Bar分贝模型(表)由基本消除使用(默认EF一到一个模型)Shared Primary Key Association从流畅的配置Map电话:

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

在这个模型中Bar表将不包含FooId FK列,而是在PK列Id也不再是身份,也将作为参考FK TABL Foo

这使得EF不在乎在Foo保持BarId,因为它知道,如果有相应的Bar,将它与Id一样Foo.Id

如果您不能更改数据库的设计,那么你的运气了 - 你要么忍受LEFT OUTER JOIN S,或牺牲Foo.Bar导航性能和配置的关系为单向一到多达你已经提及。